- New sections on the Fixed and Frame containers - Rearrange the
authorGMT 1999 Tony Gale <gale@gtk.org>
Fri, 29 Jan 1999 09:29:02 +0000 (09:29 +0000)
committerTony Gale <gale@src.gnome.org>
Fri, 29 Jan 1999 09:29:02 +0000 (09:29 +0000)
Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>

        * docs/gtk_tut.sgml:
          - New sections on the Fixed and Frame containers
          - Rearrange the Containers section so the easier ones
            are first
          - Move the List widget section to an appendix

ChangeLog
ChangeLog.pre-2-0
ChangeLog.pre-2-10
ChangeLog.pre-2-2
ChangeLog.pre-2-4
ChangeLog.pre-2-6
ChangeLog.pre-2-8
docs/gtk_tut.sgml
docs/tutorial/gtk_tut.sgml

index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index 74123c584a5a4f9fbec16f96b7158134cdca25c4..091e23d8f7c952e9035c0484ba27556aacafa9c0 100644 (file)
@@ -1,3 +1,11 @@
+Fri Jan 29 09:18:41 GMT 1999 Tony Gale  <gale@gtk.org>
+
+       * docs/gtk_tut.sgml:
+         - New sections on the Fixed and Frame containers
+         - Rearrange the Containers section so the easier ones
+           are first
+         - Move the List widget section to an appendix
+
 Thu Jan 28 12:14:12 GMT 1999 Tony Gale  <gale@gtk.org>
 
        * docs/package_tutorial.sh: script to convert and
index c85e11796dc883e98d69a81dd10db10c046d7db6..30c962a6c478818f401adb6c976bde02ea2eb91b 100644 (file)
@@ -11,7 +11,7 @@ Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
                              name="&lt;gale@gtk.org&gt;"></tt>
 Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
                              name="&lt;imain@gtk.org&gt;"></tt>,
-<date>January 27th, 1999
+<date>January 28th, 1999
 
 <!-- ***************************************************************** -->
 <sect>Introduction
@@ -4782,471 +4782,409 @@ int main (int argc, char *argv[])
 <sect> Container Widgets
 <!-- ***************************************************************** -->
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> Notebooks
-<p>
-The NoteBook Widget is a collection of 'pages' that overlap each
-other, each page contains different information. This widget has
-become more common lately in GUI programming, and it is a good way to
-show blocks of similar information that warrant separation in their
-display.
+<!-- ----------------------------------------------------------------- -->   
+<sect1>The EventBox <label id="sec_EventBox">
+<p> 
+Some GTK widgets don't have associated X windows, so they just draw on
+their parents. Because of this, they cannot receive events and if they
+are incorrectly sized, they don't clip so you can get messy
+overwriting etc. If you require more from these widgets, the EventBox
+is for you.
 
-The first function call you will need to know, as you can probably
-guess by now, is used to create a new notebook widget.
+At first glance, the EventBox widget might appear to be totally
+useless. It draws nothing on the screen and responds to no
+events. However, it does serve a function - it provides an X window
+for its child widget. This is important as many GTK widgets do not
+have an associated X window. Not having an X window saves memory and
+improves performance, but also has some drawbacks. A widget without an
+X window cannot receive events, and does not perform any clipping on
+its contents. Although the name <em/EventBox/ emphasizes the
+event-handling function, the widget can also be used for clipping.
+(and more, see the example below).
+
+To create a new EventBox widget, use:
 
 <tscreen><verb>
-GtkWidget *gtk_notebook_new( void );
+GtkWidget *gtk_event_box_new( void );
 </verb></tscreen>
 
-Once the notebook has been created, there are a number of functions
-that operate on the notebook widget. Let's look at them individually.
-
-The first one we will look at is how to position the page indicators.
-These page indicators or 'tabs' as they are referred to, can be
-positioned in four ways: top, bottom, left, or right.
+A child widget can then be added to this EventBox:
 
 <tscreen><verb>
-void gtk_notebook_set_tab_pos( GtkNotebook     *notebook,
-                               GtkPositionType  pos );
+gtk_container_add( GTK_CONTAINER(event_box), widget );
 </verb></tscreen>
 
-GtkPostionType will be one of the following, and they are pretty self explanatory:
-<itemize>
-<item> GTK_POS_LEFT
-<item> GTK_POS_RIGHT
-<item> GTK_POS_TOP
-<item> GTK_POS_BOTTOM
-</itemize>
-
-GTK_POS_TOP is the default.
-
-Next we will look at how to add pages to the notebook. There are three
-ways to add pages to the NoteBook. Let's look at the first two
-together as they are quite similar.
+The following example demonstrates both uses of an EventBox - a label
+is created that is clipped to a small box, and set up so that a
+mouse-click on the label causes the program to exit. Resizing the
+window reveals varying amounts of the label.
 
 <tscreen><verb>
-void gtk_notebook_append_page( GtkNotebook *notebook,
-                               GtkWidget   *child,
-                               GtkWidget   *tab_label );
+/* example-start eventbox eventbox.c */
 
-void gtk_notebook_prepend_page( GtkNotebook *notebook,
-                                GtkWidget   *child,
-                                GtkWidget   *tab_label );
+#include <gtk/gtk.h>
+
+int 
+main (int argc, char *argv[])
+{
+    GtkWidget *window;
+    GtkWidget *event_box;
+    GtkWidget *label;
+    
+    gtk_init (&amp;argc, &amp;argv);
+    
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    
+    gtk_window_set_title (GTK_WINDOW (window), "Event Box");
+    
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
+    
+    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+    
+    /* Create an EventBox and add it to our toplevel window */
+    
+    event_box = gtk_event_box_new ();
+    gtk_container_add (GTK_CONTAINER(window), event_box);
+    gtk_widget_show (event_box);
+    
+    /* Create a long label */
+    
+    label = gtk_label_new ("Click here to quit, quit, quit, quit, quit");
+    gtk_container_add (GTK_CONTAINER (event_box), label);
+    gtk_widget_show (label);
+    
+    /* Clip it short. */
+    gtk_widget_set_usize (label, 110, 20);
+    
+    /* And bind an action to it */
+    gtk_widget_set_events (event_box, GDK_BUTTON_PRESS_MASK);
+    gtk_signal_connect (GTK_OBJECT(event_box), "button_press_event",
+                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
+    
+    /* Yet one more thing you need an X window for ... */
+    
+    gtk_widget_realize (event_box);
+    gdk_window_set_cursor (event_box->window, gdk_cursor_new (GDK_HAND1));
+    
+    gtk_widget_show (window);
+    
+    gtk_main ();
+    
+    return(0);
+}
+/* example-end */
 </verb></tscreen>
 
-These functions add pages to the notebook by inserting them from the
-back of the notebook (append), or the front of the notebook (prepend).
-<tt/child/ is the widget that is placed within the notebook page, and
-<tt/tab_label/ is the label for the page being added. The <tt/child/
-widget must be created separately, and is typically a set of options
-setout witin one of the other container widgets, such as a table.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Fixed Container
+<p>
+The Fixed container allows you to place widgets at a fixed position
+within it's window, relative to it's upper left hand corner. The
+position of the widgets can be changed dynamically.
 
-The final function for adding a page to the notebook contains all of
-the properties of the previous two, but it allows you to specify what
-position you want the page to be in the notebook.
+There are only three functions associated with the fixed widget:
 
 <tscreen><verb>
-void gtk_notebook_insert_page( GtkNotebook *notebook,
-                               GtkWidget   *child,
-                               GtkWidget   *tab_label,
-                               gint         position );
+GtkWidget* gtk_fixed_new( void );
+
+void gtk_fixed_put( GtkFixed  *fixed,
+                    GtkWidget *widget,
+                    gint16     x,
+                    gint16     y );
+
+void gtk_fixed_move( GtkFixed  *fixed,
+                     GtkWidget *widget,
+                     gint16     x,
+                     gint16     y );
 </verb></tscreen>
 
-The parameters are the same as _append_ and _prepend_ except it
-contains an extra parameter, <tt/position/.  This parameter is used to
-specify what place this page will be inserted into.
+The function <tt/gtk_fixed_new/ allows you to create a new Fixed
+container.
 
-Now that we know how to add a page, lets see how we can remove a page
-from the notebook.
+<tt/gtk_fixed_put/ places <tt/widget/ in the container <tt/fixed/ at
+the position specified by <tt/x/ and <tt/y/.
+
+<tt/gtk_fixed_move/ allows the specified widget to be moved to a new
+position.
+
+The following example illustrates how to use the Fixed Container.
 
 <tscreen><verb>
-void gtk_notebook_remove_page( GtkNotebook *notebook,
-                               gint         page_num );
-</verb></tscreen>
+/* example-start fixed fixed.c */
 
-This function takes the page specified by <tt/page_num/ and removes it
-from the widget pointed to by <tt/notebook/.
+#include <gtk/gtk.h>
 
-To find out what the current page is in a notebook use the function:
+/* I'm going to be lazy and use some global variables to
+ * store the position of the widget within the fixed
+ * container */
+gint x=50;
+gint y=50;
 
-<tscreen><verb>
-gint gtk_notebook_get_current_page( GtkNotebook *notebook );
-</verb></tscreen>
+/* This callback function moves the button to a new position
+ * in the Fixed container. */
+void move_button( GtkWidget *widget,
+                  GtkWidget *fixed )
+{
+  x = (x+30)%300;
+  y = (y+50)%300;
+  gtk_fixed_move( GTK_FIXED(fixed), widget, x, y); 
+}
 
-These next two functions are simple calls to move the notebook page
-forward or backward. Simply provide the respective function call with
-the notebook widget you wish to operate on. Note: when the NoteBook is
-currently on the last page, and gtk_notebook_next_page is called, the
-notebook will wrap back to the first page. Likewise, if the NoteBook
-is on the first page, and gtk_notebook_prev_page is called, the
-notebook will wrap to the last page.
+int main( int   argc,
+          char *argv[] )
+{
+  /* GtkWidget is the storage type for widgets */
+  GtkWidget *window;
+  GtkWidget *fixed;
+  GtkWidget *button;
+  gint i;
 
-<tscreen><verb>
-void gtk_notebook_next_page( GtkNoteBook *notebook );
+  /* Initialise GTK */
+  gtk_init(&amp;argc, &amp;argv);
+    
+  /* Create a new window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(window), "Fixed Container");
 
-void gtk_notebook_prev_page( GtkNoteBook *notebook );
+  /* Here we connect the "destroy" event to a signal handler */ 
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+  /* Sets the border width of the window. */
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+  /* Create a Fixed Container */
+  fixed = gtk_fixed_new();
+  gtk_container_add(GTK_CONTAINER(window), fixed);
+  gtk_widget_show(fixed);
+  
+  for (i = 1 ; i <= 3 ; i++) {
+    /* Creates a new button with the label "Press me" */
+    button = gtk_button_new_with_label ("Press me");
+  
+    /* When the button receives the "clicked" signal, it will call the
+     * function move_button() passing it the Fixed Containter as its
+     * argument. */
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                       GTK_SIGNAL_FUNC (move_button), fixed);
+  
+    /* This packs the button into the fixed containers window. */
+    gtk_fixed_put (GTK_FIXED (fixed), button, i*50, i*50);
+  
+    /* The final step is to display this newly created widget. */
+    gtk_widget_show (button);
+  }
+
+  /* Display the window */
+  gtk_widget_show (window);
+    
+  /* Enter the event loop */
+  gtk_main ();
+    
+  return(0);
+}
+/* example-end */
 </verb></tscreen>
 
-This next function sets the 'active' page. If you wish the notebook to
-be opened to page 5 for example, you would use this function.  Without
-using this function, the notebook defaults to the first page.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Frames
+<p>
+Frames can be used to enclose one or a group of widgets with a box
+which can optionally be labelled. The position of the label and the
+style of the box can be altered to suit.
+
+A Frame can be created with the following function:
 
 <tscreen><verb>
-void gtk_notebook_set_page( GtkNotebook *notebook,
-                            gint         page_num );
+GtkWidget *gtk_frame_new( const gchar *label );
 </verb></tscreen>
 
-The next two functions add or remove the notebook page tabs and the
-notebook border respectively.
+The label is by default placed in the upper left hand corner of the
+frame. A value of NULL for the <tt/label/ argument will result in no
+label being displayed. The text of the label can be changed using the
+next function.
 
 <tscreen><verb>
-void gtk_notebook_set_show_tabs( GtkNotebook *notebook,
-                                 gboolean     show_tabs);
+void gtk_frame_set_label( GtkFrame    *frame,
+                          const gchar *label );
+</verb></tscreen>
 
-void gtk_notebook_set_show_border( GtkNotebook *notebook,
-                                   gboolean     show_border );
+The position of the label can be changed using this function:
+
+<tscreen><verb>
+void gtk_frame_set_label_align( GtkFrame *frame,
+                                gfloat    xalign,
+                                gfloat    yalign );
 </verb></tscreen>
 
-The next function is useful when the you have a large number of pages,
-and the tabs don't fit on the page. It allows the tabs to be scrolled
-through using two arrow buttons.
+<tt/xalign/ and <tt/yalign/ take values between 0.0 and 1.0. <tt/xalign/
+indicates the position of the label along the top horizontal of the
+frame. <tt/yalign/ is not currently used. The default value of xalign
+is 0.0 which places the label at the left hand end of the frame.
+
+The next function alters the style of the box that is used to outline
+the frame.
 
 <tscreen><verb>
-void gtk_notebook_set_scrollable( GtkNotebook *notebook,
-                                  gboolean     scrollable );
+void gtk_frame_set_shadow_type( GtkFrame      *frame,
+                                GtkShadowType  type);
 </verb></tscreen>
 
-<tt/show_tabs/, <tt/show_border/ and <tt/scrollable/ can be either
-TRUE or FALSE.
+The <tt/type/ argument can take one of the following values:
+<itemize>
+<item> GTK_SHADOW_NONE
+<item> GTK_SHADOW_IN
+<item> GTK_SHADOW_OUT
+<item> GTK_SHADOW_ETCHED_IN (the default)
+<item> GTK_SHADOW_ETCHED_OUT
+</itemize>
 
-Now lets look at an example, it is expanded from the testgtk.c code
-that comes with the GTK distribution. This small program creates a
-window with a notebook and six buttons. The notebook contains 11
-pages, added in three different ways, appended, inserted, and
-prepended. The buttons allow you rotate the tab positions, add/remove
-the tabs and border, remove a page, change pages in both a forward and
-backward manner, and exit the program.
+The following code example illustrates the use of the Frame widget.
 
 <tscreen><verb>
-/* example-start notebook notebook.c */
+/* example-start frame frame.c */
 
 #include <gtk/gtk.h>
 
-/* This function rotates the position of the tabs */
-void rotate_book (GtkButton *button, GtkNotebook *notebook)
+int main( int   argc,
+          char *argv[] )
 {
-    gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos +1) %4);
-}
+  /* GtkWidget is the storage type for widgets */
+  GtkWidget *window;
+  GtkWidget *frame;
+  GtkWidget *button;
+  gint i;
 
-/* Add/Remove the page tabs and the borders */
-void tabsborder_book (GtkButton *button, GtkNotebook *notebook)
-{
-    gint tval = FALSE;
-    gint bval = FALSE;
-    if (notebook->show_tabs == 0)
-           tval = TRUE; 
-    if (notebook->show_border == 0)
-           bval = TRUE;
+  /* Initialise GTK */
+  gtk_init(&amp;argc, &amp;argv);
     
-    gtk_notebook_set_show_tabs (notebook, tval);
-    gtk_notebook_set_show_border (notebook, bval);
-}
+  /* Create a new window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(window), "Frame Example");
 
-/* Remove a page from the notebook */
-void remove_book (GtkButton *button, GtkNotebook *notebook)
-{
-    gint page;
-    
-    page = gtk_notebook_get_current_page(notebook);
-    gtk_notebook_remove_page (notebook, page);
-    /* Need to refresh the widget -- 
-     This forces the widget to redraw itself. */
-    gtk_widget_draw(GTK_WIDGET(notebook), NULL);
-}
+  /* Here we connect the "destroy" event to a signal handler */ 
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
 
-void delete (GtkWidget *widget, GtkWidget *event, gpointer data)
-{
-    gtk_main_quit ();
-}
+  gtk_widget_set_usize(window, 300, 300);
+  /* Sets the border width of the window. */
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
 
-int main (int argc, char *argv[])
-{
-    GtkWidget *window;
-    GtkWidget *button;
-    GtkWidget *table;
-    GtkWidget *notebook;
-    GtkWidget *frame;
-    GtkWidget *label;
-    GtkWidget *checkbutton;
-    int i;
-    char bufferf[32];
-    char bufferl[32];
-    
-    gtk_init (&amp;argc, &amp;argv);
-    
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    
-    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
-                       GTK_SIGNAL_FUNC (delete), NULL);
-    
-    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+  /* Create a Frame */
+  frame = gtk_frame_new(NULL);
+  gtk_container_add(GTK_CONTAINER(window), frame);
 
-    table = gtk_table_new(3,6,FALSE);
-    gtk_container_add (GTK_CONTAINER (window), table);
-    
-    /* Create a new notebook, place the position of the tabs */
-    notebook = gtk_notebook_new ();
-    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
-    gtk_table_attach_defaults(GTK_TABLE(table), notebook, 0,6,0,1);
-    gtk_widget_show(notebook);
-    
-    /* Lets append a bunch of pages to the notebook */
-    for (i=0; i < 5; i++) {
-       sprintf(bufferf, "Append Frame %d", i+1);
-       sprintf(bufferl, "Page %d", i+1);
-       
-       frame = gtk_frame_new (bufferf);
-       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
-       gtk_widget_set_usize (frame, 100, 75);
-       gtk_widget_show (frame);
-       
-       label = gtk_label_new (bufferf);
-       gtk_container_add (GTK_CONTAINER (frame), label);
-       gtk_widget_show (label);
-       
-       label = gtk_label_new (bufferl);
-       gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
-    }
-      
-    /* Now lets add a page to a specific spot */
-    checkbutton = gtk_check_button_new_with_label ("Check me please!");
-    gtk_widget_set_usize(checkbutton, 100, 75);
-    gtk_widget_show (checkbutton);
-   
-    label = gtk_label_new ("Add page");
-    gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);
-    
-    /* Now finally lets prepend pages to the notebook */
-    for (i=0; i < 5; i++) {
-       sprintf(bufferf, "Prepend Frame %d", i+1);
-       sprintf(bufferl, "PPage %d", i+1);
-       
-       frame = gtk_frame_new (bufferf);
-       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
-       gtk_widget_set_usize (frame, 100, 75);
-       gtk_widget_show (frame);
-       
-       label = gtk_label_new (bufferf);
-       gtk_container_add (GTK_CONTAINER (frame), label);
-       gtk_widget_show (label);
-       
-       label = gtk_label_new (bufferl);
-       gtk_notebook_prepend_page (GTK_NOTEBOOK(notebook), frame, label);
-    }
-    
-    /* Set what page to start at (page 4) */
-    gtk_notebook_set_page (GTK_NOTEBOOK(notebook), 3);
+  /* Set the frames label */
+  gtk_frame_set_label( GTK_FRAME(frame), "GTK Frame Widget" );
 
-    /* Create a bunch of buttons */
-    button = gtk_button_new_with_label ("close");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              GTK_SIGNAL_FUNC (delete), NULL);
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("next page");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              (GtkSignalFunc) gtk_notebook_next_page,
-                              GTK_OBJECT (notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("prev page");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              (GtkSignalFunc) gtk_notebook_prev_page,
-                              GTK_OBJECT (notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 2,3,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("tab position");
-    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                        (GtkSignalFunc) rotate_book, GTK_OBJECT(notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 3,4,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("tabs/border on/off");
-    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                        (GtkSignalFunc) tabsborder_book,
-                        GTK_OBJECT (notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 4,5,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("remove page");
-    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                        (GtkSignalFunc) remove_book,
-                        GTK_OBJECT(notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 5,6,1,2);
-    gtk_widget_show(button);
-    
-    gtk_widget_show(table);
-    gtk_widget_show(window);
+  /* Align the label at the right of the frame */
+  gtk_frame_set_label_align( GTK_FRAME(frame), 1.0, 0.0);
+
+  /* Set the style of the frame */
+  gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
+
+  gtk_widget_show(frame);
+  
+  /* Display the window */
+  gtk_widget_show (window);
     
-    gtk_main ();
+  /* Enter the event loop */
+  gtk_main ();
     
-    return(0);
+  return(0);
 }
 /* example-end */
-</verb></tscreen>
-
-Hopefully this helps you on your way with creating notebooks for your
-GTK applications.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Scrolled Windows
-<p>
-Scrolled windows are used to create a scrollable area inside a real
-window.  You may insert any type of widget into a scrolled window, and
-it will be accessible regardless of the size by using the scrollbars.
 
-The following function is used to create a new scrolled window.
-
-<tscreen><verb>
-GtkWidget *gtk_scrolled_window_new( GtkAdjustment *hadjustment,
-                                    GtkAdjustment *vadjustment );
 </verb></tscreen>
 
-Where the first argument is the adjustment for the horizontal
-direction, and the second, the adjustment for the vertical direction.
-These are almost always set to NULL.
-
+<!-- ----------------------------------------------------------------- -->   
+<sect1> Aspect Frames
+<p>
+The aspect frame widget is like a frame widget, except that it also
+enforces the aspect ratio (that is, the ratio of the width to the
+height) of the child widget to have a certain value, adding extra
+space if necessary. This is useful, for instance, if you want to
+preview a larger image. The size of the preview should vary when the
+user resizes the window, but the aspect ratio needs to always match
+the original image.
+  
+To create a new aspect frame use:
+   
 <tscreen><verb>
-void gtk_scrolled_window_set_policy( GtkScrolledWindow *scrolled_window,
-                                     GtkPolicyType      hscrollbar_policy,
-                                     GtkPolicyType      vscrollbar_policy );
+GtkWidget *gtk_aspect_frame_new( const gchar *label,
+                                 gfloat       xalign,
+                                 gfloat       yalign,
+                                 gfloat       ratio,
+                                 gint         obey_child);
 </verb></tscreen>
-
-This sets the policy to be used with respect to the scrollbars.
-The first argument is the scrolled window you wish to change. The second
-sets the policy for the horizontal scrollbar, and the third the policy for 
-the vertical scrollbar.
-
-The policy may be one of GTK_POLICY_AUTOMATIC, or GTK_POLICY_ALWAYS.
-GTK_POLICY_AUTOMATIC will automatically decide whether you need
-scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
-there.
-
-You can then place your object into the scrolled window using the
-following function.
-
+   
+<tt/xalign/ and <tt/yalign/ specify alignment as with Alignment
+widgets. If <tt/obey_child/ is true, the aspect ratio of a child
+widget will match the aspect ratio of the ideal size it requests.
+Otherwise, it is given by <tt/ratio/.
+   
+To change the options of an existing aspect frame, you can use:
+   
 <tscreen><verb>
-void gtk_scrolled_window_add_with_viewport( GtkScrolledWindow *scrolled_window,
-                                            GtkWidget         *child);
+void gtk_aspect_frame_set( GtkAspectFrame *aspect_frame,
+                           gfloat          xalign,
+                           gfloat          yalign,
+                           gfloat          ratio,
+                           gint            obey_child);
 </verb></tscreen>
-
-Here is a simple example that packs 100 toggle buttons into a scrolled
-window.  I've only commented on the parts that may be new to you.
-
+   
+As an example, the following program uses an AspectFrame to present a
+drawing area whose aspect ratio will always be 2:1, no matter how the
+user resizes the top-level window.
+   
 <tscreen><verb>
-/* example-start scrolledwin scrolledwin.c */
+/* example-start aspectframe aspectframe.c */
 
 #include <gtk/gtk.h>
-
-void destroy(GtkWidget *widget, gpointer data)
-{
-    gtk_main_quit();
-}
-
-int main (int argc, char *argv[])
+   
+int
+main (int argc, char *argv[])
 {
-    static GtkWidget *window;
-    GtkWidget *scrolled_window;
-    GtkWidget *table;
-    GtkWidget *button;
-    char buffer[32];
-    int i, j;
-    
+    GtkWidget *window;
+    GtkWidget *aspect_frame;
+    GtkWidget *drawing_area;
     gtk_init (&amp;argc, &amp;argv);
-    
-    /* Create a new dialog window for the scrolled window to be
-     * packed into. A dialog is just like a normal window except it has a 
-     * vbox and a horizontal separator packed into it. It's just a shortcut
-     * for creating dialogs */
-    window = gtk_dialog_new ();
+   
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
     gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                       (GtkSignalFunc) destroy, NULL);
-    gtk_window_set_title (GTK_WINDOW (window), "GtkScrolledWindow example");
-    gtk_container_set_border_width (GTK_CONTAINER (window), 0);
-    gtk_widget_set_usize(window, 300, 300);
-    
-    /* create a new scrolled window. */
-    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-    
-    gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
-    
-    /* the policy is one of GTK_POLICY AUTOMATIC, or GTK_POLICY_ALWAYS.
-     * GTK_POLICY_AUTOMATIC will automatically decide whether you need
-     * scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
-     * there.  The first one is the horizontal scrollbar, the second, 
-     * the vertical. */
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
-                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-    /* The dialog window is created with a vbox packed into it. */                                                             
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window, 
-                       TRUE, TRUE, 0);
-    gtk_widget_show (scrolled_window);
-    
-    /* create a table of 10 by 10 squares. */
-    table = gtk_table_new (10, 10, FALSE);
-    
-    /* set the spacing to 10 on x and 10 on y */
-    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
-    gtk_table_set_col_spacings (GTK_TABLE (table), 10);
-    
-    /* pack the table into the scrolled window */
-    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
-                                           table);
-    gtk_widget_show (table);
-    
-    /* this simply creates a grid of toggle buttons on the table
-     * to demonstrate the scrolled window. */
-    for (i = 0; i < 10; i++)
-       for (j = 0; j < 10; j++) {
-          sprintf (buffer, "button (%d,%d)\n", i, j);
-         button = gtk_toggle_button_new_with_label (buffer);
-         gtk_table_attach_defaults (GTK_TABLE (table), button,
-                                    i, i+1, j, j+1);
-          gtk_widget_show (button);
-       }
-    
-    /* Add a "close" button to the bottom of the dialog */
-    button = gtk_button_new_with_label ("close");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              (GtkSignalFunc) gtk_widget_destroy,
-                              GTK_OBJECT (window));
-    
-    /* this makes it so the button is the default. */
-    
-    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
-    
-    /* This grabs this button to be the default button. Simply hitting
-     * the "Enter" key will cause this button to activate. */
-    gtk_widget_grab_default (button);
-    gtk_widget_show (button);
-    
+                        GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+   
+    /* Create an aspect_frame and add it to our toplevel window */
+   
+    aspect_frame = gtk_aspect_frame_new ("2x1", /* label */
+                                         0.5, /* center x */
+                                         0.5, /* center y */
+                                         2, /* xsize/ysize = 2 */
+                                         FALSE /* ignore child's aspect */);
+   
+    gtk_container_add (GTK_CONTAINER(window), aspect_frame);
+    gtk_widget_show (aspect_frame);
+   
+    /* Now add a child widget to the aspect frame */
+   
+    drawing_area = gtk_drawing_area_new ();
+   
+    /* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
+     * window since we are forcing a 2x1 aspect ratio */
+    gtk_widget_set_usize (drawing_area, 200, 200);
+    gtk_container_add (GTK_CONTAINER(aspect_frame), drawing_area);
+    gtk_widget_show (drawing_area);
+   
     gtk_widget_show (window);
-    
-    gtk_main();
-    
-    return(0);
+    gtk_main ();
+    return 0;
 }
 /* example-end */
 </verb></tscreen>
 
-Try playing with resizing the window. You'll notice how the scrollbars
-react. You may also wish to use the gtk_widget_set_usize() call to set
-the default size of the window or other widgets.
-
 <!-- ----------------------------------------------------------------- -->   
 <sect1> Paned Window Widgets
 <p>
@@ -5451,6 +5389,152 @@ main (int argc, char *argv[])
 /* example-end */
 </verb></tscreen>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>Scrolled Windows
+<p>
+Scrolled windows are used to create a scrollable area inside a real
+window.  You may insert any type of widget into a scrolled window, and
+it will be accessible regardless of the size by using the scrollbars.
+
+The following function is used to create a new scrolled window.
+
+<tscreen><verb>
+GtkWidget *gtk_scrolled_window_new( GtkAdjustment *hadjustment,
+                                    GtkAdjustment *vadjustment );
+</verb></tscreen>
+
+Where the first argument is the adjustment for the horizontal
+direction, and the second, the adjustment for the vertical direction.
+These are almost always set to NULL.
+
+<tscreen><verb>
+void gtk_scrolled_window_set_policy( GtkScrolledWindow *scrolled_window,
+                                     GtkPolicyType      hscrollbar_policy,
+                                     GtkPolicyType      vscrollbar_policy );
+</verb></tscreen>
+
+This sets the policy to be used with respect to the scrollbars.
+The first argument is the scrolled window you wish to change. The second
+sets the policy for the horizontal scrollbar, and the third the policy for 
+the vertical scrollbar.
+
+The policy may be one of GTK_POLICY_AUTOMATIC, or GTK_POLICY_ALWAYS.
+GTK_POLICY_AUTOMATIC will automatically decide whether you need
+scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
+there.
+
+You can then place your object into the scrolled window using the
+following function.
+
+<tscreen><verb>
+void gtk_scrolled_window_add_with_viewport( GtkScrolledWindow *scrolled_window,
+                                            GtkWidget         *child);
+</verb></tscreen>
+
+Here is a simple example that packs 100 toggle buttons into a scrolled
+window.  I've only commented on the parts that may be new to you.
+
+<tscreen><verb>
+/* example-start scrolledwin scrolledwin.c */
+
+#include <gtk/gtk.h>
+
+void destroy(GtkWidget *widget, gpointer data)
+{
+    gtk_main_quit();
+}
+
+int main (int argc, char *argv[])
+{
+    static GtkWidget *window;
+    GtkWidget *scrolled_window;
+    GtkWidget *table;
+    GtkWidget *button;
+    char buffer[32];
+    int i, j;
+    
+    gtk_init (&amp;argc, &amp;argv);
+    
+    /* Create a new dialog window for the scrolled window to be
+     * packed into. A dialog is just like a normal window except it has a 
+     * vbox and a horizontal separator packed into it. It's just a shortcut
+     * for creating dialogs */
+    window = gtk_dialog_new ();
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                       (GtkSignalFunc) destroy, NULL);
+    gtk_window_set_title (GTK_WINDOW (window), "GtkScrolledWindow example");
+    gtk_container_set_border_width (GTK_CONTAINER (window), 0);
+    gtk_widget_set_usize(window, 300, 300);
+    
+    /* create a new scrolled window. */
+    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+    
+    gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
+    
+    /* the policy is one of GTK_POLICY AUTOMATIC, or GTK_POLICY_ALWAYS.
+     * GTK_POLICY_AUTOMATIC will automatically decide whether you need
+     * scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
+     * there.  The first one is the horizontal scrollbar, the second, 
+     * the vertical. */
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+    /* The dialog window is created with a vbox packed into it. */                                                             
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window, 
+                       TRUE, TRUE, 0);
+    gtk_widget_show (scrolled_window);
+    
+    /* create a table of 10 by 10 squares. */
+    table = gtk_table_new (10, 10, FALSE);
+    
+    /* set the spacing to 10 on x and 10 on y */
+    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
+    gtk_table_set_col_spacings (GTK_TABLE (table), 10);
+    
+    /* pack the table into the scrolled window */
+    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
+                                           table);
+    gtk_widget_show (table);
+    
+    /* this simply creates a grid of toggle buttons on the table
+     * to demonstrate the scrolled window. */
+    for (i = 0; i < 10; i++)
+       for (j = 0; j < 10; j++) {
+          sprintf (buffer, "button (%d,%d)\n", i, j);
+         button = gtk_toggle_button_new_with_label (buffer);
+         gtk_table_attach_defaults (GTK_TABLE (table), button,
+                                    i, i+1, j, j+1);
+          gtk_widget_show (button);
+       }
+    
+    /* Add a "close" button to the bottom of the dialog */
+    button = gtk_button_new_with_label ("close");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              (GtkSignalFunc) gtk_widget_destroy,
+                              GTK_OBJECT (window));
+    
+    /* this makes it so the button is the default. */
+    
+    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
+    
+    /* This grabs this button to be the default button. Simply hitting
+     * the "Enter" key will cause this button to activate. */
+    gtk_widget_grab_default (button);
+    gtk_widget_show (button);
+    
+    gtk_widget_show (window);
+    
+    gtk_main();
+    
+    return(0);
+}
+/* example-end */
+</verb></tscreen>
+
+Try playing with resizing the window. You'll notice how the scrollbars
+react. You may also wish to use the gtk_widget_set_usize() call to set
+the default size of the window or other widgets.
+
 <!-- ----------------------------------------------------------------- -->   
 <sect1>Toolbar
 <p>
@@ -5884,226 +5968,364 @@ static char * gtk_xpm[] = {
 ".............++++..............."};
 </verb></tscreen>
 
-<!-- ----------------------------------------------------------------- -->   
-<sect1> Aspect Frames
+<!-- ----------------------------------------------------------------- -->
+<sect1> Notebooks
 <p>
-The aspect frame widget is like a frame widget, except that it also
-enforces the aspect ratio (that is, the ratio of the width to the
-height) of the child widget to have a certain value, adding extra
-space if necessary. This is useful, for instance, if you want to
-preview a larger image. The size of the preview should vary when the
-user resizes the window, but the aspect ratio needs to always match
-the original image.
-  
-To create a new aspect frame use:
-   
-<tscreen><verb>
-GtkWidget *gtk_aspect_frame_new( const gchar *label,
-                                 gfloat       xalign,
-                                 gfloat       yalign,
-                                 gfloat       ratio,
-                                 gint         obey_child);
-</verb></tscreen>
-   
-<tt/xalign/ and <tt/yalign/ specify alignment as with Alignment
-widgets. If <tt/obey_child/ is true, the aspect ratio of a child
-widget will match the aspect ratio of the ideal size it requests.
-Otherwise, it is given by <tt/ratio/.
-   
-To change the options of an existing aspect frame, you can use:
-   
+The NoteBook Widget is a collection of 'pages' that overlap each
+other, each page contains different information. This widget has
+become more common lately in GUI programming, and it is a good way to
+show blocks of similar information that warrant separation in their
+display.
+
+The first function call you will need to know, as you can probably
+guess by now, is used to create a new notebook widget.
+
 <tscreen><verb>
-void gtk_aspect_frame_set( GtkAspectFrame *aspect_frame,
-                           gfloat          xalign,
-                           gfloat          yalign,
-                           gfloat          ratio,
-                           gint            obey_child);
+GtkWidget *gtk_notebook_new( void );
 </verb></tscreen>
-   
-As an example, the following program uses an AspectFrame to present a
-drawing area whose aspect ratio will always be 2:1, no matter how the
-user resizes the top-level window.
-   
-<tscreen><verb>
-/* example-start aspectframe aspectframe.c */
 
-#include <gtk/gtk.h>
-   
-int
-main (int argc, char *argv[])
-{
-    GtkWidget *window;
-    GtkWidget *aspect_frame;
-    GtkWidget *drawing_area;
-    gtk_init (&amp;argc, &amp;argv);
-   
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
-    gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                        GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
-    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
-   
-    /* Create an aspect_frame and add it to our toplevel window */
-   
-    aspect_frame = gtk_aspect_frame_new ("2x1", /* label */
-                                         0.5, /* center x */
-                                         0.5, /* center y */
-                                         2, /* xsize/ysize = 2 */
-                                         FALSE /* ignore child's aspect */);
-   
-    gtk_container_add (GTK_CONTAINER(window), aspect_frame);
-    gtk_widget_show (aspect_frame);
-   
-    /* Now add a child widget to the aspect frame */
-   
-    drawing_area = gtk_drawing_area_new ();
-   
-    /* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
-     * window since we are forcing a 2x1 aspect ratio */
-    gtk_widget_set_usize (drawing_area, 200, 200);
-    gtk_container_add (GTK_CONTAINER(aspect_frame), drawing_area);
-    gtk_widget_show (drawing_area);
-   
-    gtk_widget_show (window);
-    gtk_main ();
-    return 0;
-}
-/* example-end */
+Once the notebook has been created, there are a number of functions
+that operate on the notebook widget. Let's look at them individually.
+
+The first one we will look at is how to position the page indicators.
+These page indicators or 'tabs' as they are referred to, can be
+positioned in four ways: top, bottom, left, or right.
+
+<tscreen><verb>
+void gtk_notebook_set_tab_pos( GtkNotebook     *notebook,
+                               GtkPositionType  pos );
 </verb></tscreen>
 
-<!-- ----------------------------------------------------------------- -->   
-<sect1>The EventBox <label id="sec_EventBox">
-<p> 
-Some gtk widgets don't have associated X windows, so they just draw on
-their parents. Because of this, they cannot receive events and if they
-are incorrectly sized, they don't clip so you can get messy
-overwriting etc. If you require more from these widgets, the EventBox
-is for you.
+GtkPostionType will be one of the following, and they are pretty self explanatory:
+<itemize>
+<item> GTK_POS_LEFT
+<item> GTK_POS_RIGHT
+<item> GTK_POS_TOP
+<item> GTK_POS_BOTTOM
+</itemize>
 
-At first glance, the EventBox widget might appear to be totally
-useless. It draws nothing on the screen and responds to no
-events. However, it does serve a function - it provides an X window
-for its child widget. This is important as many GTK widgets do not
-have an associated X window. Not having an X window saves memory and
-improves performance, but also has some drawbacks. A widget without an
-X window cannot receive events, and does not perform any clipping on
-its contents. Although the name <em/EventBox/ emphasizes the
-event-handling function, the widget can also be used for clipping.
-(and more, see the example below).
+GTK_POS_TOP is the default.
 
-To create a new EventBox widget, use:
+Next we will look at how to add pages to the notebook. There are three
+ways to add pages to the NoteBook. Let's look at the first two
+together as they are quite similar.
 
 <tscreen><verb>
-GtkWidget *gtk_event_box_new( void );
+void gtk_notebook_append_page( GtkNotebook *notebook,
+                               GtkWidget   *child,
+                               GtkWidget   *tab_label );
+
+void gtk_notebook_prepend_page( GtkNotebook *notebook,
+                                GtkWidget   *child,
+                                GtkWidget   *tab_label );
 </verb></tscreen>
 
-A child widget can then be added to this EventBox:
+These functions add pages to the notebook by inserting them from the
+back of the notebook (append), or the front of the notebook (prepend).
+<tt/child/ is the widget that is placed within the notebook page, and
+<tt/tab_label/ is the label for the page being added. The <tt/child/
+widget must be created separately, and is typically a set of options
+setout witin one of the other container widgets, such as a table.
+
+The final function for adding a page to the notebook contains all of
+the properties of the previous two, but it allows you to specify what
+position you want the page to be in the notebook.
 
 <tscreen><verb>
-gtk_container_add( GTK_CONTAINER(event_box), widget );
+void gtk_notebook_insert_page( GtkNotebook *notebook,
+                               GtkWidget   *child,
+                               GtkWidget   *tab_label,
+                               gint         position );
 </verb></tscreen>
 
-The following example demonstrates both uses of an EventBox - a label
-is created that is clipped to a small box, and set up so that a
-mouse-click on the label causes the program to exit. Resizing the
-window reveals varying amounts of the label.
-
-<tscreen><verb>
-/* example-start eventbox eventbox.c */
+The parameters are the same as _append_ and _prepend_ except it
+contains an extra parameter, <tt/position/.  This parameter is used to
+specify what place this page will be inserted into.
 
-#include <gtk/gtk.h>
+Now that we know how to add a page, lets see how we can remove a page
+from the notebook.
 
-int 
-main (int argc, char *argv[])
-{
-    GtkWidget *window;
-    GtkWidget *event_box;
-    GtkWidget *label;
-    
-    gtk_init (&amp;argc, &amp;argv);
-    
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    
-    gtk_window_set_title (GTK_WINDOW (window), "Event Box");
-    
-    gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
-    
-    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
-    
-    /* Create an EventBox and add it to our toplevel window */
-    
-    event_box = gtk_event_box_new ();
-    gtk_container_add (GTK_CONTAINER(window), event_box);
-    gtk_widget_show (event_box);
-    
-    /* Create a long label */
-    
-    label = gtk_label_new ("Click here to quit, quit, quit, quit, quit");
-    gtk_container_add (GTK_CONTAINER (event_box), label);
-    gtk_widget_show (label);
-    
-    /* Clip it short. */
-    gtk_widget_set_usize (label, 110, 20);
-    
-    /* And bind an action to it */
-    gtk_widget_set_events (event_box, GDK_BUTTON_PRESS_MASK);
-    gtk_signal_connect (GTK_OBJECT(event_box), "button_press_event",
-                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
-    
-    /* Yet one more thing you need an X window for ... */
-    
-    gtk_widget_realize (event_box);
-    gdk_window_set_cursor (event_box->window, gdk_cursor_new (GDK_HAND1));
-    
-    gtk_widget_show (window);
-    
-    gtk_main ();
-    
-    return(0);
-}
-/* example-end */
+<tscreen><verb>
+void gtk_notebook_remove_page( GtkNotebook *notebook,
+                               gint         page_num );
 </verb></tscreen>
 
-<!-- ***************************************************************** -->
-<sect>CList Widget
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<p>
-The GtkCList widget has replaced the GtkList widget (which is still
-available).
+This function takes the page specified by <tt/page_num/ and removes it
+from the widget pointed to by <tt/notebook/.
 
-The GtkCList widget is a multi-column list widget that is capable of
-handling literally thousands of rows of information. Each column can
-optionally have a title, which itself is optionally active, allowing
-us to bind a function to its selection.
+To find out what the current page is in a notebook use the function:
 
-<!-- ----------------------------------------------------------------- -->
-<sect1>Creating a GtkCList widget
-<p>
-Creating a GtkCList is quite straightforward, once you have learned
-about widgets in general. It provides the almost standard two ways,
-that is the hard way, and the easy way. But before we create it, there
-is one thing we should figure out beforehand: how many columns should
-it have?
+<tscreen><verb>
+gint gtk_notebook_get_current_page( GtkNotebook *notebook );
+</verb></tscreen>
 
-Not all columns have to be visible and can be used to store data that
-is related to a certain cell in the list.
+These next two functions are simple calls to move the notebook page
+forward or backward. Simply provide the respective function call with
+the notebook widget you wish to operate on. Note: when the NoteBook is
+currently on the last page, and gtk_notebook_next_page is called, the
+notebook will wrap back to the first page. Likewise, if the NoteBook
+is on the first page, and gtk_notebook_prev_page is called, the
+notebook will wrap to the last page.
 
 <tscreen><verb>
-GtkWidget *gtk_clist_new ( gint columns );
+void gtk_notebook_next_page( GtkNoteBook *notebook );
 
-GtkWidget *gtk_clist_new_with_titles( gint   columns,
-                                      gchar *titles[] );
+void gtk_notebook_prev_page( GtkNoteBook *notebook );
 </verb></tscreen>
 
-The first form is very straight forward, the second might require some
-explanation. Each column can have a title associated with it, and this
-title can be a label or a button that reacts when we click on it. If
-we use the second form, we must provide pointers to the title texts,
-and the number of pointers should equal the number of columns
-specified. Of course we can always use the first form, and manually
+This next function sets the 'active' page. If you wish the notebook to
+be opened to page 5 for example, you would use this function.  Without
+using this function, the notebook defaults to the first page.
+
+<tscreen><verb>
+void gtk_notebook_set_page( GtkNotebook *notebook,
+                            gint         page_num );
+</verb></tscreen>
+
+The next two functions add or remove the notebook page tabs and the
+notebook border respectively.
+
+<tscreen><verb>
+void gtk_notebook_set_show_tabs( GtkNotebook *notebook,
+                                 gboolean     show_tabs);
+
+void gtk_notebook_set_show_border( GtkNotebook *notebook,
+                                   gboolean     show_border );
+</verb></tscreen>
+
+The next function is useful when the you have a large number of pages,
+and the tabs don't fit on the page. It allows the tabs to be scrolled
+through using two arrow buttons.
+
+<tscreen><verb>
+void gtk_notebook_set_scrollable( GtkNotebook *notebook,
+                                  gboolean     scrollable );
+</verb></tscreen>
+
+<tt/show_tabs/, <tt/show_border/ and <tt/scrollable/ can be either
+TRUE or FALSE.
+
+Now lets look at an example, it is expanded from the testgtk.c code
+that comes with the GTK distribution. This small program creates a
+window with a notebook and six buttons. The notebook contains 11
+pages, added in three different ways, appended, inserted, and
+prepended. The buttons allow you rotate the tab positions, add/remove
+the tabs and border, remove a page, change pages in both a forward and
+backward manner, and exit the program.
+
+<tscreen><verb>
+/* example-start notebook notebook.c */
+
+#include <gtk/gtk.h>
+
+/* This function rotates the position of the tabs */
+void rotate_book (GtkButton *button, GtkNotebook *notebook)
+{
+    gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos +1) %4);
+}
+
+/* Add/Remove the page tabs and the borders */
+void tabsborder_book (GtkButton *button, GtkNotebook *notebook)
+{
+    gint tval = FALSE;
+    gint bval = FALSE;
+    if (notebook->show_tabs == 0)
+           tval = TRUE; 
+    if (notebook->show_border == 0)
+           bval = TRUE;
+    
+    gtk_notebook_set_show_tabs (notebook, tval);
+    gtk_notebook_set_show_border (notebook, bval);
+}
+
+/* Remove a page from the notebook */
+void remove_book (GtkButton *button, GtkNotebook *notebook)
+{
+    gint page;
+    
+    page = gtk_notebook_get_current_page(notebook);
+    gtk_notebook_remove_page (notebook, page);
+    /* Need to refresh the widget -- 
+     This forces the widget to redraw itself. */
+    gtk_widget_draw(GTK_WIDGET(notebook), NULL);
+}
+
+void delete (GtkWidget *widget, GtkWidget *event, gpointer data)
+{
+    gtk_main_quit ();
+}
+
+int main (int argc, char *argv[])
+{
+    GtkWidget *window;
+    GtkWidget *button;
+    GtkWidget *table;
+    GtkWidget *notebook;
+    GtkWidget *frame;
+    GtkWidget *label;
+    GtkWidget *checkbutton;
+    int i;
+    char bufferf[32];
+    char bufferl[32];
+    
+    gtk_init (&amp;argc, &amp;argv);
+    
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    
+    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                       GTK_SIGNAL_FUNC (delete), NULL);
+    
+    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+    table = gtk_table_new(3,6,FALSE);
+    gtk_container_add (GTK_CONTAINER (window), table);
+    
+    /* Create a new notebook, place the position of the tabs */
+    notebook = gtk_notebook_new ();
+    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
+    gtk_table_attach_defaults(GTK_TABLE(table), notebook, 0,6,0,1);
+    gtk_widget_show(notebook);
+    
+    /* Lets append a bunch of pages to the notebook */
+    for (i=0; i < 5; i++) {
+       sprintf(bufferf, "Append Frame %d", i+1);
+       sprintf(bufferl, "Page %d", i+1);
+       
+       frame = gtk_frame_new (bufferf);
+       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+       gtk_widget_set_usize (frame, 100, 75);
+       gtk_widget_show (frame);
+       
+       label = gtk_label_new (bufferf);
+       gtk_container_add (GTK_CONTAINER (frame), label);
+       gtk_widget_show (label);
+       
+       label = gtk_label_new (bufferl);
+       gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+    }
+      
+    /* Now lets add a page to a specific spot */
+    checkbutton = gtk_check_button_new_with_label ("Check me please!");
+    gtk_widget_set_usize(checkbutton, 100, 75);
+    gtk_widget_show (checkbutton);
+   
+    label = gtk_label_new ("Add page");
+    gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);
+    
+    /* Now finally lets prepend pages to the notebook */
+    for (i=0; i < 5; i++) {
+       sprintf(bufferf, "Prepend Frame %d", i+1);
+       sprintf(bufferl, "PPage %d", i+1);
+       
+       frame = gtk_frame_new (bufferf);
+       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+       gtk_widget_set_usize (frame, 100, 75);
+       gtk_widget_show (frame);
+       
+       label = gtk_label_new (bufferf);
+       gtk_container_add (GTK_CONTAINER (frame), label);
+       gtk_widget_show (label);
+       
+       label = gtk_label_new (bufferl);
+       gtk_notebook_prepend_page (GTK_NOTEBOOK(notebook), frame, label);
+    }
+    
+    /* Set what page to start at (page 4) */
+    gtk_notebook_set_page (GTK_NOTEBOOK(notebook), 3);
+
+    /* Create a bunch of buttons */
+    button = gtk_button_new_with_label ("close");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              GTK_SIGNAL_FUNC (delete), NULL);
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("next page");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              (GtkSignalFunc) gtk_notebook_next_page,
+                              GTK_OBJECT (notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("prev page");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              (GtkSignalFunc) gtk_notebook_prev_page,
+                              GTK_OBJECT (notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 2,3,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("tab position");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                        (GtkSignalFunc) rotate_book, GTK_OBJECT(notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 3,4,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("tabs/border on/off");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                        (GtkSignalFunc) tabsborder_book,
+                        GTK_OBJECT (notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 4,5,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("remove page");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                        (GtkSignalFunc) remove_book,
+                        GTK_OBJECT(notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 5,6,1,2);
+    gtk_widget_show(button);
+    
+    gtk_widget_show(table);
+    gtk_widget_show(window);
+    
+    gtk_main ();
+    
+    return(0);
+}
+/* example-end */
+</verb></tscreen>
+
+Hopefully this helps you on your way with creating notebooks for your
+GTK applications.
+
+<!-- ***************************************************************** -->
+<sect>CList Widget
+<!-- ***************************************************************** -->
+
+<!-- ----------------------------------------------------------------- -->
+<p>
+The GtkCList widget has replaced the GtkList widget (which is still
+available).
+
+The GtkCList widget is a multi-column list widget that is capable of
+handling literally thousands of rows of information. Each column can
+optionally have a title, which itself is optionally active, allowing
+us to bind a function to its selection.
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Creating a GtkCList widget
+<p>
+Creating a GtkCList is quite straightforward, once you have learned
+about widgets in general. It provides the almost standard two ways,
+that is the hard way, and the easy way. But before we create it, there
+is one thing we should figure out beforehand: how many columns should
+it have?
+
+Not all columns have to be visible and can be used to store data that
+is related to a certain cell in the list.
+
+<tscreen><verb>
+GtkWidget *gtk_clist_new ( gint columns );
+
+GtkWidget *gtk_clist_new_with_titles( gint   columns,
+                                      gchar *titles[] );
+</verb></tscreen>
+
+The first form is very straight forward, the second might require some
+explanation. Each column can have a title associated with it, and this
+title can be a label or a button that reacts when we click on it. If
+we use the second form, we must provide pointers to the title texts,
+and the number of pointers should equal the number of columns
+specified. Of course we can always use the first form, and manually
 add titles later.
 
 Note: the GtkCList widget does not have it's own scrollbars and should
@@ -6781,1059 +7003,446 @@ void selection_made( GtkWidget *clist, gint row, gint column,
 </verb></tscreen>
                     
 <!-- ***************************************************************** -->
-<sect> List Widget
+<sect> Tree Widget<label id="sec_Tree_Widgets">
 <!-- ***************************************************************** -->
 <p>
-NOTE: The GtkList widget has been superseded by the GtkCList widget.
-
-The GtkList widget is designed to act as a vertical container for
-widgets that should be of the type GtkListItem.
+The purpose of tree widgets is to display hierarchically-organized
+data. The GtkTree widget itself is a vertical container for widgets of
+type GtkTreeItem. GtkTree itself is not terribly different from
+GtkList - both are derived directly from GtkContainer, and the
+GtkContainer methods work in the same way on GtkTree widgets as on
+GtkList widgets. The difference is that GtkTree widgets can be nested
+within other GtkTree widgets. We'll see how to do this shortly.
 
-A GtkList widget has its own window to receive events and its own
-background color which is usually white. As it is directly derived
-from a GtkContainer it can be treated as such by using the
-GTK_CONTAINER(List) macro, see the GtkContainer widget for more on
-this. One should already be familiar with the usage of a GList and
-its related functions g_list_*() to be able to use the GtkList widget
-to it full extent.
+The GtkTree widget has its own window, and defaults to a white
+background, as does GtkList. Also, most of the GtkTree methods work in
+the same way as the corresponding GtkList ones. However, GtkTree is
+not derived from GtkList, so you cannot use them interchangeably.
 
-There is one field inside the structure definition of the GtkList
-widget that will be of greater interest to us, this is:
+<sect1> Creating a Tree
+<p>
+A GtkTree is created in the usual way, using:
 
 <tscreen><verb>
-struct _GtkList
-{
-  ...
-  GList *selection;
-  guint selection_mode;
-  ...
-}; 
+GtkWidget* gtk_tree_new( void );
 </verb></tscreen>
 
-The selection field of a GtkList points to a linked list of all items
-that are currently selected, or NULL if the selection is empty.  So to
-learn about the current selection we read the GTK_LIST()->selection
-field, but do not modify it since the internal fields are maintained
-by the gtk_list_*() functions.
+Like the GtkList widget, a GtkTree will simply keep growing as more
+items are added to it, as well as when subtrees are expanded.  For
+this reason, they are almost always packed into a
+GtkScrolledWindow. You might want to use gtk_widget_set_usize() on the
+scrolled window to ensure that it is big enough to see the tree's
+items, as the default size for GtkScrolledWindow is quite small.
 
-The selection_mode of the GtkList determines the selection facilities
-of a GtkList and therefore the contents of the GTK_LIST()->selection
-field. The selection_mode may be one of the following:
+Now that you have a tree, you'll probably want to add some items to
+it.  <ref id="sec_Tree_Item_Widget" name="The Tree Item Widget"> below
+explains the gory details of GtkTreeItem. For now, it'll suffice to
+create one, using:
 
-<itemize>
-<item> GTK_SELECTION_SINGLE - The selection is either NULL
-                        or contains a GList pointer
-                        for a single selected item.
+<tscreen><verb>
+GtkWidget* gtk_tree_item_new_with_label( gchar *label );
+</verb></tscreen>
 
-<item> GTK_SELECTION_BROWSE -  The selection is NULL if the list
-                        contains no widgets or insensitive
-                        ones only, otherwise it contains
-                        a GList pointer for one GList
-                        structure, and therefore exactly
-                        one list item.
+You can then add it to the tree using one of the following (see
+<ref id="sec_GtkTree_Functions" name="Functions and Macros">
+below for more options):
 
-<item> GTK_SELECTION_MULTIPLE -  The selection is NULL if no list
-                        items are selected or a GList pointer
-                        for the first selected item. That
-                        in turn points to a GList structure
-                        for the second selected item and so
-                        on.
+<tscreen><verb>
+void gtk_tree_append( GtkTree    *tree,
+                       GtkWidget *tree_item );
 
-<item> GTK_SELECTION_EXTENDED - The selection is always NULL.
-</itemize>
+void gtk_tree_prepend( GtkTree   *tree,
+                       GtkWidget *tree_item );
+</verb></tscreen>
 
-The default is GTK_SELECTION_MULTIPLE.
+Note that you must add items to a GtkTree one at a time - there is no
+equivalent to gtk_list_*_items().
 
 <!-- ----------------------------------------------------------------- -->
-<sect1> Signals
+<sect1> Adding a Subtree
 <p>
+A subtree is created like any other GtkTree widget. A subtree is added
+to another tree beneath a tree item, using:
+
 <tscreen><verb>
-void selection_changed( GtkList *list );
+void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,
+                                GtkWidget   *subtree );
 </verb></tscreen>
 
-This signal will be invoked whenever the selection field of a GtkList
-has changed. This happens when a child of the GtkList got selected or
-deselected.
+You do not need to call gtk_widget_show() on a subtree before or after
+adding it to a GtkTreeItem. However, you <em>must</em> have added the
+GtkTreeItem in question to a parent tree before calling
+gtk_tree_item_set_subtree(). This is because, technically, the parent
+of the subtree is <em>not</em> the GtkTreeItem which "owns" it, but
+rather the GtkTree which holds that GtkTreeItem.
 
-<tscreen><verb>
-void select_child( GtkList   *list,
-                   GtkWidget *child);
-</verb></tscreen>
+When you add a subtree to a GtkTreeItem, a plus or minus sign appears
+beside it, which the user can click on to "expand" or "collapse" it,
+meaning, to show or hide its subtree. GtkTreeItems are collapsed by
+default. Note that when you collapse a GtkTreeItem, any selected
+items in its subtree remain selected, which may not be what the user
+expects.
 
-This signal is invoked when a child of the GtkList is about to get
-selected. This happens mainly on calls to gtk_list_select_item(),
-gtk_list_select_child(), button presses and sometimes indirectly
-triggered on some else occasions where children get added to or
-removed from the GtkList.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Handling the Selection List
+<p>
+As with GtkList, the GtkTree type has a <tt>selection</tt> field, and
+it is possible to control the behaviour of the tree (somewhat) by
+setting the selection type using:
 
 <tscreen><verb>
-void unselect_child( GtkList   *list,
-                     GtkWidget *child );
+void gtk_tree_set_selection_mode( GtkTree          *tree,
+                                  GtkSelectionMode  mode );
 </verb></tscreen>
 
-This signal is invoked when a child of the GtkList is about to get
-deselected. This happens mainly on calls to gtk_list_unselect_item(),
-gtk_list_unselect_child(), button presses and sometimes indirectly
-triggered on some else occasions where children get added to or
-removed from the GtkList.
+The semantics associated with the various selection modes are
+described in the section on the GtkList widget. As with the GtkList
+widget, the "select_child", "unselect_child" (not really - see <ref
+id="sec_GtkTree_Signals" name="Signals"> below for an explanation),
+and "selection_changed" signals are emitted when list items are
+selected or unselected. However, in order to take advantage of these
+signals, you need to know <em>which</em> GtkTree widget they will be
+emitted by, and where to find the list of selected items.
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> Functions
+This is a source of potential confusion. The best way to explain this
+is that though all GtkTree widgets are created equal, some are more
+equal than others. All GtkTree widgets have their own X window, and
+can therefore receive events such as mouse clicks (if their
+GtkTreeItems or their children don't catch them first!). However, to
+make GTK_SELECTION_SINGLE and GTK_SELECTION_BROWSE selection types
+behave in a sane manner, the list of selected items is specific to the
+topmost GtkTree widget in a hierarchy, known as the "root tree".
+
+Thus, accessing the <tt>selection</tt>field directly in an arbitrary
+GtkTree widget is not a good idea unless you <em>know</em> it's the
+root tree.  Instead, use the GTK_TREE_SELECTION (Tree) macro, which
+gives the root tree's selection list as a GList pointer. Of course,
+this list can include items that are not in the subtree in question if 
+the selection type is GTK_SELECTION_MULTIPLE.
+
+Finally, the "select_child" (and "unselect_child", in theory) signals
+are emitted by all trees, but the "selection_changed" signal is only
+emitted by the root tree. Consequently, if you want to handle the
+"select_child" signal for a tree and all its subtrees, you will have
+to call gtk_signal_connect() for every subtree.
+
+<sect1> Tree Widget Internals
 <p>
+The GtkTree's struct definition looks like this:
+
 <tscreen><verb>
-guint gtk_list_get_type( void );
+struct _GtkTree
+{
+  GtkContainer container;
+
+  GList *children;
+  
+  GtkTree* root_tree; /* owner of selection list */
+  GtkWidget* tree_owner;
+  GList *selection;
+  guint level;
+  guint indent_value;
+  guint current_indent;
+  guint selection_mode : 2;
+  guint view_mode : 1;
+  guint view_line : 1;
+};
 </verb></tscreen>
 
-Returns the `GtkList' type identifier.
+The perils associated with accessing the <tt>selection</tt> field
+directly have already been mentioned. The other important fields of
+the struct can also be accessed with handy macros or class functions.
+GTK_TREE_IS_ROOT_TREE (Tree) returns a boolean value which indicates
+whether a tree is the root tree in a GtkTree hierarchy, while
+GTK_TREE_ROOT_TREE (Tree) returns the root tree, an object of type
+GtkTree (so, remember to cast it using GTK_WIDGET (Tree) if you want
+to use one of the gtk_widget_*() functions on it).
+
+Instead of directly accessing the children field of a GtkTree widget,
+it's probably best to cast it using GTK_CONTAINER (Tree), and pass it
+to the gtk_container_children() function. This creates a duplicate of
+the original list, so it's advisable to free it up using g_list_free()
+after you're done with it, or to iterate on it destructively, like
+this:
 
 <tscreen><verb>
-GtkWidget *gtk_list_new( void );
+    children = gtk_container_children (GTK_CONTAINER (tree));
+    while (children) {
+      do_something_nice (GTK_TREE_ITEM (children->data));
+      children = g_list_remove_link (children, children);
+}
 </verb></tscreen>
 
-Create a new GtkList object. The new widget is returned as a pointer
-to a GtkWidget object. NULL is returned on failure.
+The <tt>tree_owner</tt> field is defined only in subtrees, where it
+points to the GtkTreeItem widget which holds the tree in question.
+The <tt>level</tt> field indicates how deeply nested a particular tree
+is; root trees have level 0, and each successive level of subtrees has
+a level one greater than the parent level. This field is set only
+after a GtkTree widget is actually mapped (i.e. drawn on the screen).
 
+<sect2> Signals<label id="sec_GtkTree_Signals">
+<p>
 <tscreen><verb>
-void gtk_list_insert_items( GtkList *list,
-                            GList   *items,
-                            gint     position );
+void selection_changed( GtkTree *tree );
 </verb></tscreen>
 
-Insert list items into the list, starting at <tt/position/.
-<tt/items/ is a doubly linked list where each nodes data pointer is
-expected to point to a newly created GtkListItem.  The GList nodes of
-<tt/items/ are taken over by the list.
+This signal will be emitted whenever the <tt>selection</tt> field of a
+GtkTree has changed. This happens when a child of the GtkTree is
+selected or deselected.
 
 <tscreen><verb>
-void gtk_list_append_items( GtkList *list,
-                            GList   *items);
+void select_child( GtkTree   *tree,
+                   GtkWidget *child );
 </verb></tscreen>
 
-Insert list items just like gtk_list_insert_items() at the end of the
-list. The GList nodes of <tt/items/ are taken over by the list.
+This signal is emitted when a child of the GtkTree is about to get
+selected. This happens on calls to gtk_tree_select_item(),
+gtk_tree_select_child(), on <em>all</em> button presses and calls to
+gtk_tree_item_toggle() and gtk_item_toggle().  It may sometimes be
+indirectly triggered on other occasions where children get added to or
+removed from the GtkTree.
 
 <tscreen><verb>
-void gtk_list_prepend_items( GtkList *list,
-                             GList   *items);
+void unselect_child (GtkTree   *tree,
+                     GtkWidget *child);
 </verb></tscreen>
 
-Insert list items just like gtk_list_insert_items() at the very
-beginning of the list. The GList nodes of <tt/items/ are taken over by
-the list.
+This signal is emitted when a child of the GtkTree is about to get
+deselected. As of GTK+ 1.0.4, this seems to only occur on calls to
+gtk_tree_unselect_item() or gtk_tree_unselect_child(), and perhaps on
+other occasions, but <em>not</em> when a button press deselects a
+child, nor on emission of the "toggle" signal by gtk_item_toggle().
 
+<sect2> Functions and Macros<label id="sec_GtkTree_Functions">
+<p>
 <tscreen><verb>
-void gtk_list_remove_items( GtkList *list,
-                            GList   *items);
+guint gtk_tree_get_type( void );
 </verb></tscreen>
 
-Remove list items from the list. <tt/items/ is a doubly linked list
-where each nodes data pointer is expected to point to a direct child
-of list. It is the callers responsibility to make a call to
-g_list_free(items) afterwards. Also the caller has to destroy the list
-items himself.
+Returns the `GtkTree' type identifier.
 
 <tscreen><verb>
-void gtk_list_clear_items( GtkList *list,
-                           gint start,
-                           gint end );
+GtkWidget* gtk_tree_new( void );
 </verb></tscreen>
 
-Remove and destroy list items from the list. A widget is affected if
-its current position within the list is in the range specified by
-<tt/start/ and <tt/end/.
+Create a new GtkTree object. The new widget is returned as a pointer
+to a GtkWidget object. NULL is returned on failure.
 
 <tscreen><verb>
-void gtk_list_select_item( GtkList *list,
+void gtk_tree_append( GtkTree   *tree,
+                      GtkWidget *tree_item );
+</verb></tscreen>
+
+Append a tree item to a GtkTree.
+
+<tscreen><verb>
+void gtk_tree_prepend( GtkTree   *tree,
+                       GtkWidget *tree_item );
+</verb></tscreen>
+
+Prepend a tree item to a GtkTree.
+
+<tscreen><verb>
+void gtk_tree_insert( GtkTree   *tree,
+                      GtkWidget *tree_item,
+                      gint       position );
+</verb></tscreen>
+
+Insert a tree item into a GtkTree at the position in the list
+specified by <tt>position.</tt>
+
+<tscreen><verb>
+void gtk_tree_remove_items( GtkTree *tree,
+                            GList   *items );
+</verb></tscreen>
+
+Remove a list of items (in the form of a GList *) from a GtkTree.
+Note that removing an item from a tree dereferences (and thus usually)
+destroys it <em>and</em> its subtree, if it has one, <em>and</em> all
+subtrees in that subtree.  If you want to remove only one item, you
+can use gtk_container_remove().
+
+<tscreen><verb>
+void gtk_tree_clear_items( GtkTree *tree,
+                           gint     start,
+                           gint     end );
+</verb></tscreen>
+
+Remove the items from position <tt>start</tt> to position <tt>end</tt>
+from a GtkTree.  The same warning about dereferencing applies here, as
+gtk_tree_clear_items() simply constructs a list and passes it to
+gtk_tree_remove_items().
+
+<tscreen><verb>
+void gtk_tree_select_item( GtkTree *tree,
                            gint     item );
 </verb></tscreen>
 
-Invoke the select_child signal for a list item specified through its
-current position within the list.
+Emits the "select_item" signal for the child at position
+<tt>item</tt>, thus selecting the child (unless you unselect it in a
+signal handler).
 
 <tscreen><verb>
-void gtk_list_unselect_item( GtkList *list,
-                             gint     item);
+void gtk_tree_unselect_item( GtkTree *tree,
+                             gint     item );
 </verb></tscreen>
 
-Invoke the unselect_child signal for a list item specified through its
-current position within the list.
+Emits the "unselect_item" signal for the child at position
+<tt>item</tt>, thus unselecting the child.
 
 <tscreen><verb>
-void gtk_list_select_child( GtkList *list,
-                            GtkWidget *child);
+void gtk_tree_select_child( GtkTree   *tree,
+                            GtkWidget *tree_item );
 </verb></tscreen>
 
-Invoke the select_child signal for the specified child.
+Emits the "select_item" signal for the child <tt>tree_item</tt>, thus
+selecting it.
 
 <tscreen><verb>
-void gtk_list_unselect_child( GtkList   *list,
-                              GtkWidget *child);
+void gtk_tree_unselect_child( GtkTree   *tree,
+                              GtkWidget *tree_item );
 </verb></tscreen>
 
-Invoke the unselect_child signal for the specified child.
+Emits the "unselect_item" signal for the child <tt>tree_item</tt>,
+thus unselecting it.
 
 <tscreen><verb>
-gint gtk_list_child_position( GtkList *list,
-                              GtkWidget *child);
+gint gtk_tree_child_position( GtkTree   *tree,
+                              GtkWidget *child );
 </verb></tscreen>
 
-Return the position of <tt/child/ within the list. "-1" is returned on
-failure.
+Returns the position in the tree of <tt>child</tt>, unless
+<tt>child</tt> is not in the tree, in which case it returns -1.
 
 <tscreen><verb>
-void gtk_list_set_selection_mode( GtkList         *list,
-                                  GtkSelectionMode mode );
+void gtk_tree_set_selection_mode( GtkTree          *tree,
+                                  GtkSelectionMode  mode );
 </verb></tscreen>
 
-Set the selection mode MODE which can be of GTK_SELECTION_SINGLE,
-GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or
-GTK_SELECTION_EXTENDED.
+Sets the selection mode, which can be one of GTK_SELECTION_SINGLE (the
+default), GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE, or
+GTK_SELECTION_EXTENDED. This is only defined for root trees, which
+makes sense, since the root tree "owns" the selection. Setting it for
+subtrees has no effect at all; the value is simply ignored.
 
 <tscreen><verb>
-GtkList *GTK_LIST( gpointer obj );
+void gtk_tree_set_view_mode( GtkTree         *tree,
+                             GtkTreeViewMode  mode ); 
 </verb></tscreen>
 
-Cast a generic pointer to `GtkList *'. *Note Standard Macros::, for
-more info.
+Sets the "view mode", which can be either GTK_TREE_VIEW_LINE (the
+default) or GTK_TREE_VIEW_ITEM.  The view mode propagates from a tree
+to its subtrees, and can't be set exclusively to a subtree (this is
+not exactly true - see the example code comments).
+
+The term "view mode" is rather ambiguous - basically, it controls the
+way the highlight is drawn when one of a tree's children is selected.
+If it's GTK_TREE_VIEW_LINE, the entire GtkTreeItem widget is
+highlighted, while for GTK_TREE_VIEW_ITEM, only the child widget
+(i.e. usually the label) is highlighted.
 
 <tscreen><verb>
-GtkListClass *GTK_LIST_CLASS( gpointer class);
+void gtk_tree_set_view_lines( GtkTree *tree,
+                              guint    flag );
 </verb></tscreen>
 
-Cast a generic pointer to `GtkListClass*'. *Note Standard Macros::,
-for more info.
+Controls whether connecting lines between tree items are drawn.
+<tt>flag</tt> is either TRUE, in which case they are, or FALSE, in
+which case they aren't.
 
 <tscreen><verb>
-gint GTK_IS_LIST( gpointer obj);
+GtkTree *GTK_TREE (gpointer obj);
 </verb></tscreen>
 
-Determine if a generic pointer refers to a `GtkList' object. *Note
-Standard Macros::, for more info.
+Cast a generic pointer to `GtkTree *'.
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> Example
+<tscreen><verb>
+GtkTreeClass *GTK_TREE_CLASS (gpointer class);
+</verb></tscreen>
+
+Cast a generic pointer to `GtkTreeClass*'.
+
+<tscreen><verb>
+gint GTK_IS_TREE (gpointer obj);
+</verb></tscreen>
+
+Determine if a generic pointer refers to a `GtkTree' object.
+
+<tscreen><verb>
+gint GTK_IS_ROOT_TREE (gpointer obj)
+</verb></tscreen>
+
+Determine if a generic pointer refers to a `GtkTree' object
+<em>and</em> is a root tree. Though this will accept any pointer, the
+results of passing it a pointer that does not refer to a GtkTree are
+undefined and possibly harmful.
+
+<tscreen><verb>
+GtkTree *GTK_TREE_ROOT_TREE (gpointer obj)
+</verb></tscreen>
+
+Return the root tree of a pointer to a `GtkTree' object. The above
+warning applies.
+
+<tscreen><verb>
+GList *GTK_TREE_SELECTION( gpointer obj)
+</verb></tscreen>
+
+Return the selection list of the root tree of a `GtkTree' object. The
+above warning applies here, too.
+
+<sect1> Tree Item Widget<label id="sec_Tree_Item_Widget">
 <p>
-Following is an example program that will print out the changes of the
-selection of a GtkList, and lets you "arrest" list items into a prison
-by selecting them with the rightmost mouse button.
+The GtkTreeItem widget, like GtkListItem, is derived from GtkItem,
+which in turn is derived from GtkBin.  Therefore, the item itself is a
+generic container holding exactly one child widget, which can be of
+any type.  The GtkTreeItem widget has a number of extra fields, but
+the only one we need be concerned with is the <tt>subtree</tt> field.
+
+The definition for the GtkTreeItem struct looks like this:
 
 <tscreen><verb>
-/* example-start list list.c */
+struct _GtkTreeItem
+{
+  GtkItem item;
 
-/* Include the gtk+ header files
- * Include stdio.h, we need that for the printf() function
- */
-#include        <gtk/gtk.h>
-#include        <stdio.h>
+  GtkWidget *subtree;
+  GtkWidget *pixmaps_box;
+  GtkWidget *plus_pix_widget, *minus_pix_widget;
 
-/* This is our data identification string to store
- * data in list items
- */
-const gchar *list_item_data_key="list_item_data";
+  GList *pixmaps;              /* pixmap node for this items color depth */
 
+  guint expanded : 1;
+};
+</verb></tscreen>
 
-/* prototypes for signal handler that we are going to connect
- * to the GtkList widget
- */
-static void  sigh_print_selection( GtkWidget *gtklist,
-                                   gpointer   func_data);
+The <tt>pixmaps_box</tt> field is a GtkEventBox which catches clicks
+on the plus/minus symbol which controls expansion and collapsing.  The
+<tt>pixmaps</tt> field points to an internal data structure.  Since
+you can always obtain the subtree of a GtkTreeItem in a (relatively)
+type-safe manner with the GTK_TREE_ITEM_SUBTREE (Item) macro, it's
+probably advisable never to touch the insides of a GtkTreeItem unless
+you <em>really</em> know what you're doing.
 
-static void  sigh_button_event( GtkWidget      *gtklist,
-                                GdkEventButton *event,
-                                GtkWidget      *frame );
+Since it is directly derived from a GtkItem it can be treated as such
+by using the GTK_ITEM (TreeItem) macro. A GtkTreeItem usually holds a
+label, so the convenience function gtk_list_item_new_with_label() is
+provided. The same effect can be achieved using code like the
+following, which is actually copied verbatim from
+gtk_tree_item_new_with_label():
 
+<tscreen><verb>
+tree_item = gtk_tree_item_new ();
+label_widget = gtk_label_new (label);
+gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
 
-/* Main function to set up the user interface */
+gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
+gtk_widget_show (label_widget);
+</verb></tscreen>
 
-gint main (int    argc,
-           gchar *argv[])
-{                                  
-    GtkWidget *separator;
-    GtkWidget *window;
-    GtkWidget *vbox;
-    GtkWidget *scrolled_window;
-    GtkWidget *frame;
-    GtkWidget *gtklist;
-    GtkWidget *button;
-    GtkWidget *list_item;
-    GList *dlist;
-    guint i;
-    gchar buffer[64];
-    
-    
-    /* Initialize gtk+ (and subsequently gdk) */
-
-    gtk_init(&amp;argc, &amp;argv);
-    
-    
-    /* Create a window to put all the widgets in
-     * connect gtk_main_quit() to the "destroy" event of
-     * the window to handle window manager close-window-events
-     */
-    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
-    gtk_signal_connect(GTK_OBJECT(window),
-                      "destroy",
-                      GTK_SIGNAL_FUNC(gtk_main_quit),
-                      NULL);
-    
-    
-    /* Inside the window we need a box to arrange the widgets
-     * vertically */
-    vbox=gtk_vbox_new(FALSE, 5);
-    gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
-    gtk_container_add(GTK_CONTAINER(window), vbox);
-    gtk_widget_show(vbox);
-    
-    /* This is the scrolled window to put the GtkList widget inside */
-    scrolled_window=gtk_scrolled_window_new(NULL, NULL);
-    gtk_widget_set_usize(scrolled_window, 250, 150);
-    gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
-    gtk_widget_show(scrolled_window);
-    
-    /* Create the GtkList widget.
-     * Connect the sigh_print_selection() signal handler
-     * function to the "selection_changed" signal of the GtkList
-     * to print out the selected items each time the selection
-     * has changed */
-    gtklist=gtk_list_new();
-    gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
-                                           gtklist);
-    gtk_widget_show(gtklist);
-    gtk_signal_connect(GTK_OBJECT(gtklist),
-                      "selection_changed",
-                      GTK_SIGNAL_FUNC(sigh_print_selection),
-                      NULL);
-    
-    /* We create a "Prison" to put a list item in ;) */
-    frame=gtk_frame_new("Prison");
-    gtk_widget_set_usize(frame, 200, 50);
-    gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
-    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
-    gtk_container_add(GTK_CONTAINER(vbox), frame);
-    gtk_widget_show(frame);
-    
-    /* Connect the sigh_button_event() signal handler to the GtkList
-     * which will handle the "arresting" of list items
-     */
-    gtk_signal_connect(GTK_OBJECT(gtklist),
-                      "button_release_event",
-                      GTK_SIGNAL_FUNC(sigh_button_event),
-                      frame);
-    
-    /* Create a separator */
-    separator=gtk_hseparator_new();
-    gtk_container_add(GTK_CONTAINER(vbox), separator);
-    gtk_widget_show(separator);
-    
-    /* Finally create a button and connect it's "clicked" signal
-     * to the destruction of the window */
-    button=gtk_button_new_with_label("Close");
-    gtk_container_add(GTK_CONTAINER(vbox), button);
-    gtk_widget_show(button);
-    gtk_signal_connect_object(GTK_OBJECT(button),
-                             "clicked",
-                             GTK_SIGNAL_FUNC(gtk_widget_destroy),
-                             GTK_OBJECT(window));
-    
-    
-    /* Now we create 5 list items, each having it's own
-     * label and add them to the GtkList using gtk_container_add()
-     * Also we query the text string from the label and
-     * associate it with the list_item_data_key for each list item
-     */
-    for (i=0; i<5; i++) {
-       GtkWidget       *label;
-       gchar           *string;
-       
-       sprintf(buffer, "ListItemContainer with Label #%d", i);
-       label=gtk_label_new(buffer);
-       list_item=gtk_list_item_new();
-       gtk_container_add(GTK_CONTAINER(list_item), label);
-       gtk_widget_show(label);
-       gtk_container_add(GTK_CONTAINER(gtklist), list_item);
-       gtk_widget_show(list_item);
-       gtk_label_get(GTK_LABEL(label), &amp;string);
-       gtk_object_set_data(GTK_OBJECT(list_item),
-                           list_item_data_key,
-                           string);
-    }
-    /* Here, we are creating another 5 labels, this time
-     * we use gtk_list_item_new_with_label() for the creation
-     * we can't query the text string from the label because
-     * we don't have the labels pointer and therefore
-     * we just associate the list_item_data_key of each
-     * list item with the same text string.
-     * For adding of the list items we put them all into a doubly
-     * linked list (GList), and then add them by a single call to
-     * gtk_list_append_items().
-     * Because we use g_list_prepend() to put the items into the
-     * doubly linked list, their order will be descending (instead
-     * of ascending when using g_list_append())
-     */
-    dlist=NULL;
-    for (; i<10; i++) {
-       sprintf(buffer, "List Item with Label %d", i);
-       list_item=gtk_list_item_new_with_label(buffer);
-       dlist=g_list_prepend(dlist, list_item);
-       gtk_widget_show(list_item);
-       gtk_object_set_data(GTK_OBJECT(list_item),
-                           list_item_data_key,
-                           "ListItem with integrated Label");
-    }
-    gtk_list_append_items(GTK_LIST(gtklist), dlist);
-    
-    /* Finally we want to see the window, don't we? ;) */
-    gtk_widget_show(window);
-    
-    /* Fire up the main event loop of gtk */
-    gtk_main();
-    
-    /* We get here after gtk_main_quit() has been called which
-     * happens if the main window gets destroyed
-     */
-    return(0);
-}
-
-/* This is the signal handler that got connected to button
- * press/release events of the GtkList
- */
-void sigh_button_event( GtkWidget      *gtklist,
-                        GdkEventButton *event,
-                        GtkWidget      *frame )
-{
-    /* We only do something if the third (rightmost mouse button
-     * was released
-     */
-    if (event->type==GDK_BUTTON_RELEASE &amp;&amp;
-       event->button==3) {
-       GList           *dlist, *free_list;
-       GtkWidget       *new_prisoner;
-       
-       /* Fetch the currently selected list item which
-        * will be our next prisoner ;)
-        */
-       dlist=GTK_LIST(gtklist)->selection;
-       if (dlist)
-               new_prisoner=GTK_WIDGET(dlist->data);
-       else
-               new_prisoner=NULL;
-       
-       /* Look for already imprisoned list items, we
-        * will put them back into the list.
-        * Remember to free the doubly linked list that
-        * gtk_container_children() returns
-        */
-       dlist=gtk_container_children(GTK_CONTAINER(frame));
-       free_list=dlist;
-       while (dlist) {
-           GtkWidget       *list_item;
-           
-           list_item=dlist->data;
-           
-           gtk_widget_reparent(list_item, gtklist);
-           
-           dlist=dlist->next;
-       }
-       g_list_free(free_list);
-       
-       /* If we have a new prisoner, remove him from the
-        * GtkList and put him into the frame "Prison".
-        * We need to unselect the item first.
-        */
-       if (new_prisoner) {
-           GList   static_dlist;
-           
-           static_dlist.data=new_prisoner;
-           static_dlist.next=NULL;
-           static_dlist.prev=NULL;
-           
-           gtk_list_unselect_child(GTK_LIST(gtklist),
-                                   new_prisoner);
-           gtk_widget_reparent(new_prisoner, frame);
-       }
-    }
-}
-
-/* This is the signal handler that gets called if GtkList
- * emits the "selection_changed" signal
- */
-void sigh_print_selection( GtkWidget *gtklist,
-                           gpointer   func_data)
-{
-    GList   *dlist;
-    
-    /* Fetch the doubly linked list of selected items
-     * of the GtkList, remember to treat this as read-only!
-     */
-    dlist=GTK_LIST(gtklist)->selection;
-    
-    /* If there are no selected items there is nothing more
-     * to do than just telling the user so
-     */
-    if (!dlist) {
-       g_print("Selection cleared\n");
-       return;
-    }
-    /* Ok, we got a selection and so we print it
-     */
-    g_print("The selection is a ");
-    
-    /* Get the list item from the doubly linked list
-     * and then query the data associated with list_item_data_key.
-     * We then just print it */
-    while (dlist) {
-       GtkObject       *list_item;
-       gchar           *item_data_string;
-       
-       list_item=GTK_OBJECT(dlist->data);
-       item_data_string=gtk_object_get_data(list_item,
-                                            list_item_data_key);
-       g_print("%s ", item_data_string);
-       
-       dlist=dlist->next;
-    }
-    g_print("\n");
-}
-/* example-end */
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> List Item Widget
-<p>
-The GtkListItem widget is designed to act as a container holding up to
-one child, providing functions for selection/deselection just like the
-GtkList widget requires them for its children.
-
-A GtkListItem has its own window to receive events and has its own
-background color which is usually white.
-
-As it is directly derived from a GtkItem it can be treated as such by
-using the GTK_ITEM(ListItem) macro, see the GtkItem widget for more on
-this. Usually a GtkListItem just holds a label to identify e.g. a
-filename within a GtkList -- therefore the convenience function
-gtk_list_item_new_with_label() is provided. The same effect can be
-achieved by creating a GtkLabel on its own, setting its alignment to
-xalign=0 and yalign=0.5 with a subsequent container addition to the
-GtkListItem.
-
-As one is not forced to add a GtkLabel to a GtkListItem, you could
-also add a GtkVBox or a GtkArrow etc. to the GtkListItem.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Signals
-<p>
-A GtkListItem does not create new signals on its own, but inherits
-the signals of a GtkItem. *Note GtkItem::, for more info.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Functions
-<p>
-<tscreen><verb>
-guint gtk_list_item_get_type( void );
-</verb></tscreen>
-
-Returns the `GtkListItem' type identifier.
-
-<tscreen><verb>
-GtkWidget *gtk_list_item_new( void );
-</verb></tscreen>
-
-Create a new GtkListItem object. The new widget is returned as a
-pointer to a GtkWidget object. NULL is returned on failure.
-
-<tscreen><verb>
-GtkWidget *gtk_list_item_new_with_label( gchar *label );
-</verb></tscreen>
-
-Create a new GtkListItem object, having a single GtkLabel as the sole
-child. The new widget is returned as a pointer to a GtkWidget
-object. NULL is returned on failure.
-
-<tscreen><verb>
-void gtk_list_item_select( GtkListItem *list_item );
-</verb></tscreen>
-
-This function is basically a wrapper around a call to gtk_item_select
-(GTK_ITEM (list_item)) which will emit the select signal.  *Note
-GtkItem::, for more info.
-
-<tscreen><verb>
-void gtk_list_item_deselect( GtkListItem *list_item );
-</verb></tscreen>
-
-This function is basically a wrapper around a call to
-gtk_item_deselect (GTK_ITEM (list_item)) which will emit the deselect
-signal.  *Note GtkItem::, for more info.
-
-<tscreen><verb>
-GtkListItem *GTK_LIST_ITEM( gpointer obj );
-</verb></tscreen>
-
-Cast a generic pointer to `GtkListItem*'. *Note Standard Macros::, for
-more info.
-
-<tscreen><verb>
-GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class );
-</verb></tscreen>
-
-Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::,
-for more info.
-
-<tscreen><verb>
-gint GTK_IS_LIST_ITEM( gpointer obj );
-</verb></tscreen>
-
-Determine if a generic pointer refers to a `GtkListItem' object.
-*Note Standard Macros::, for more info.
-<!-- ----------------------------------------------------------------- -->
-<sect1> Example
-<p>
-Please see the GtkList example on this, which covers the usage of a
-GtkListItem as well.
-
-<!-- ***************************************************************** -->
-<sect> Tree Widget<label id="sec_Tree_Widgets">
-<!-- ***************************************************************** -->
-<p>
-The purpose of tree widgets is to display hierarchically-organized
-data. The GtkTree widget itself is a vertical container for widgets of
-type GtkTreeItem. GtkTree itself is not terribly different from
-GtkList - both are derived directly from GtkContainer, and the
-GtkContainer methods work in the same way on GtkTree widgets as on
-GtkList widgets. The difference is that GtkTree widgets can be nested
-within other GtkTree widgets. We'll see how to do this shortly.
-
-The GtkTree widget has its own window, and defaults to a white
-background, as does GtkList. Also, most of the GtkTree methods work in
-the same way as the corresponding GtkList ones. However, GtkTree is
-not derived from GtkList, so you cannot use them interchangeably.
-
-<sect1> Creating a Tree
-<p>
-A GtkTree is created in the usual way, using:
-
-<tscreen><verb>
-GtkWidget* gtk_tree_new( void );
-</verb></tscreen>
-
-Like the GtkList widget, a GtkTree will simply keep growing as more
-items are added to it, as well as when subtrees are expanded.  For
-this reason, they are almost always packed into a
-GtkScrolledWindow. You might want to use gtk_widget_set_usize() on the
-scrolled window to ensure that it is big enough to see the tree's
-items, as the default size for GtkScrolledWindow is quite small.
-
-Now that you have a tree, you'll probably want to add some items to
-it.  <ref id="sec_Tree_Item_Widget" name="The Tree Item Widget"> below
-explains the gory details of GtkTreeItem. For now, it'll suffice to
-create one, using:
-
-<tscreen><verb>
-GtkWidget* gtk_tree_item_new_with_label( gchar *label );
-</verb></tscreen>
-
-You can then add it to the tree using one of the following (see
-<ref id="sec_GtkTree_Functions" name="Functions and Macros">
-below for more options):
-
-<tscreen><verb>
-void gtk_tree_append( GtkTree    *tree,
-                       GtkWidget *tree_item );
-
-void gtk_tree_prepend( GtkTree   *tree,
-                       GtkWidget *tree_item );
-</verb></tscreen>
-
-Note that you must add items to a GtkTree one at a time - there is no
-equivalent to gtk_list_*_items().
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Adding a Subtree
-<p>
-A subtree is created like any other GtkTree widget. A subtree is added
-to another tree beneath a tree item, using:
-
-<tscreen><verb>
-void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,
-                                GtkWidget   *subtree );
-</verb></tscreen>
-
-You do not need to call gtk_widget_show() on a subtree before or after
-adding it to a GtkTreeItem. However, you <em>must</em> have added the
-GtkTreeItem in question to a parent tree before calling
-gtk_tree_item_set_subtree(). This is because, technically, the parent
-of the subtree is <em>not</em> the GtkTreeItem which "owns" it, but
-rather the GtkTree which holds that GtkTreeItem.
-
-When you add a subtree to a GtkTreeItem, a plus or minus sign appears
-beside it, which the user can click on to "expand" or "collapse" it,
-meaning, to show or hide its subtree. GtkTreeItems are collapsed by
-default. Note that when you collapse a GtkTreeItem, any selected
-items in its subtree remain selected, which may not be what the user
-expects.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Handling the Selection List
-<p>
-As with GtkList, the GtkTree type has a <tt>selection</tt> field, and
-it is possible to control the behaviour of the tree (somewhat) by
-setting the selection type using:
-
-<tscreen><verb>
-void gtk_tree_set_selection_mode( GtkTree          *tree,
-                                  GtkSelectionMode  mode );
-</verb></tscreen>
-
-The semantics associated with the various selection modes are
-described in the section on the GtkList widget. As with the GtkList
-widget, the "select_child", "unselect_child" (not really - see <ref
-id="sec_GtkTree_Signals" name="Signals"> below for an explanation),
-and "selection_changed" signals are emitted when list items are
-selected or unselected. However, in order to take advantage of these
-signals, you need to know <em>which</em> GtkTree widget they will be
-emitted by, and where to find the list of selected items.
-
-This is a source of potential confusion. The best way to explain this
-is that though all GtkTree widgets are created equal, some are more
-equal than others. All GtkTree widgets have their own X window, and
-can therefore receive events such as mouse clicks (if their
-GtkTreeItems or their children don't catch them first!). However, to
-make GTK_SELECTION_SINGLE and GTK_SELECTION_BROWSE selection types
-behave in a sane manner, the list of selected items is specific to the
-topmost GtkTree widget in a hierarchy, known as the "root tree".
-
-Thus, accessing the <tt>selection</tt>field directly in an arbitrary
-GtkTree widget is not a good idea unless you <em>know</em> it's the
-root tree.  Instead, use the GTK_TREE_SELECTION (Tree) macro, which
-gives the root tree's selection list as a GList pointer. Of course,
-this list can include items that are not in the subtree in question if 
-the selection type is GTK_SELECTION_MULTIPLE.
-
-Finally, the "select_child" (and "unselect_child", in theory) signals
-are emitted by all trees, but the "selection_changed" signal is only
-emitted by the root tree. Consequently, if you want to handle the
-"select_child" signal for a tree and all its subtrees, you will have
-to call gtk_signal_connect() for every subtree.
-
-<sect1> Tree Widget Internals
-<p>
-The GtkTree's struct definition looks like this:
-
-<tscreen><verb>
-struct _GtkTree
-{
-  GtkContainer container;
-
-  GList *children;
-  
-  GtkTree* root_tree; /* owner of selection list */
-  GtkWidget* tree_owner;
-  GList *selection;
-  guint level;
-  guint indent_value;
-  guint current_indent;
-  guint selection_mode : 2;
-  guint view_mode : 1;
-  guint view_line : 1;
-};
-</verb></tscreen>
-
-The perils associated with accessing the <tt>selection</tt> field
-directly have already been mentioned. The other important fields of
-the struct can also be accessed with handy macros or class functions.
-GTK_TREE_IS_ROOT_TREE (Tree) returns a boolean value which indicates
-whether a tree is the root tree in a GtkTree hierarchy, while
-GTK_TREE_ROOT_TREE (Tree) returns the root tree, an object of type
-GtkTree (so, remember to cast it using GTK_WIDGET (Tree) if you want
-to use one of the gtk_widget_*() functions on it).
-
-Instead of directly accessing the children field of a GtkTree widget,
-it's probably best to cast it using GTK_CONTAINER (Tree), and pass it
-to the gtk_container_children() function. This creates a duplicate of
-the original list, so it's advisable to free it up using g_list_free()
-after you're done with it, or to iterate on it destructively, like
-this:
-
-<tscreen><verb>
-    children = gtk_container_children (GTK_CONTAINER (tree));
-    while (children) {
-      do_something_nice (GTK_TREE_ITEM (children->data));
-      children = g_list_remove_link (children, children);
-}
-</verb></tscreen>
-
-The <tt>tree_owner</tt> field is defined only in subtrees, where it
-points to the GtkTreeItem widget which holds the tree in question.
-The <tt>level</tt> field indicates how deeply nested a particular tree
-is; root trees have level 0, and each successive level of subtrees has
-a level one greater than the parent level. This field is set only
-after a GtkTree widget is actually mapped (i.e. drawn on the screen).
-
-<sect2> Signals<label id="sec_GtkTree_Signals">
-<p>
-<tscreen><verb>
-void selection_changed( GtkTree *tree );
-</verb></tscreen>
-
-This signal will be emitted whenever the <tt>selection</tt> field of a
-GtkTree has changed. This happens when a child of the GtkTree is
-selected or deselected.
-
-<tscreen><verb>
-void select_child( GtkTree   *tree,
-                   GtkWidget *child );
-</verb></tscreen>
-
-This signal is emitted when a child of the GtkTree is about to get
-selected. This happens on calls to gtk_tree_select_item(),
-gtk_tree_select_child(), on <em>all</em> button presses and calls to
-gtk_tree_item_toggle() and gtk_item_toggle().  It may sometimes be
-indirectly triggered on other occasions where children get added to or
-removed from the GtkTree.
-
-<tscreen><verb>
-void unselect_child (GtkTree   *tree,
-                     GtkWidget *child);
-</verb></tscreen>
-
-This signal is emitted when a child of the GtkTree is about to get
-deselected. As of GTK+ 1.0.4, this seems to only occur on calls to
-gtk_tree_unselect_item() or gtk_tree_unselect_child(), and perhaps on
-other occasions, but <em>not</em> when a button press deselects a
-child, nor on emission of the "toggle" signal by gtk_item_toggle().
-
-<sect2> Functions and Macros<label id="sec_GtkTree_Functions">
-<p>
-<tscreen><verb>
-guint gtk_tree_get_type( void );
-</verb></tscreen>
-
-Returns the `GtkTree' type identifier.
-
-<tscreen><verb>
-GtkWidget* gtk_tree_new( void );
-</verb></tscreen>
-
-Create a new GtkTree object. The new widget is returned as a pointer
-to a GtkWidget object. NULL is returned on failure.
-
-<tscreen><verb>
-void gtk_tree_append( GtkTree   *tree,
-                      GtkWidget *tree_item );
-</verb></tscreen>
-
-Append a tree item to a GtkTree.
-
-<tscreen><verb>
-void gtk_tree_prepend( GtkTree   *tree,
-                       GtkWidget *tree_item );
-</verb></tscreen>
-
-Prepend a tree item to a GtkTree.
-
-<tscreen><verb>
-void gtk_tree_insert( GtkTree   *tree,
-                      GtkWidget *tree_item,
-                      gint       position );
-</verb></tscreen>
-
-Insert a tree item into a GtkTree at the position in the list
-specified by <tt>position.</tt>
-
-<tscreen><verb>
-void gtk_tree_remove_items( GtkTree *tree,
-                            GList   *items );
-</verb></tscreen>
-
-Remove a list of items (in the form of a GList *) from a GtkTree.
-Note that removing an item from a tree dereferences (and thus usually)
-destroys it <em>and</em> its subtree, if it has one, <em>and</em> all
-subtrees in that subtree.  If you want to remove only one item, you
-can use gtk_container_remove().
-
-<tscreen><verb>
-void gtk_tree_clear_items( GtkTree *tree,
-                           gint     start,
-                           gint     end );
-</verb></tscreen>
-
-Remove the items from position <tt>start</tt> to position <tt>end</tt>
-from a GtkTree.  The same warning about dereferencing applies here, as
-gtk_tree_clear_items() simply constructs a list and passes it to
-gtk_tree_remove_items().
-
-<tscreen><verb>
-void gtk_tree_select_item( GtkTree *tree,
-                           gint     item );
-</verb></tscreen>
-
-Emits the "select_item" signal for the child at position
-<tt>item</tt>, thus selecting the child (unless you unselect it in a
-signal handler).
-
-<tscreen><verb>
-void gtk_tree_unselect_item( GtkTree *tree,
-                             gint     item );
-</verb></tscreen>
-
-Emits the "unselect_item" signal for the child at position
-<tt>item</tt>, thus unselecting the child.
-
-<tscreen><verb>
-void gtk_tree_select_child( GtkTree   *tree,
-                            GtkWidget *tree_item );
-</verb></tscreen>
-
-Emits the "select_item" signal for the child <tt>tree_item</tt>, thus
-selecting it.
-
-<tscreen><verb>
-void gtk_tree_unselect_child( GtkTree   *tree,
-                              GtkWidget *tree_item );
-</verb></tscreen>
-
-Emits the "unselect_item" signal for the child <tt>tree_item</tt>,
-thus unselecting it.
-
-<tscreen><verb>
-gint gtk_tree_child_position( GtkTree   *tree,
-                              GtkWidget *child );
-</verb></tscreen>
-
-Returns the position in the tree of <tt>child</tt>, unless
-<tt>child</tt> is not in the tree, in which case it returns -1.
-
-<tscreen><verb>
-void gtk_tree_set_selection_mode( GtkTree          *tree,
-                                  GtkSelectionMode  mode );
-</verb></tscreen>
-
-Sets the selection mode, which can be one of GTK_SELECTION_SINGLE (the
-default), GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE, or
-GTK_SELECTION_EXTENDED. This is only defined for root trees, which
-makes sense, since the root tree "owns" the selection. Setting it for
-subtrees has no effect at all; the value is simply ignored.
-
-<tscreen><verb>
-void gtk_tree_set_view_mode( GtkTree         *tree,
-                             GtkTreeViewMode  mode ); 
-</verb></tscreen>
-
-Sets the "view mode", which can be either GTK_TREE_VIEW_LINE (the
-default) or GTK_TREE_VIEW_ITEM.  The view mode propagates from a tree
-to its subtrees, and can't be set exclusively to a subtree (this is
-not exactly true - see the example code comments).
-
-The term "view mode" is rather ambiguous - basically, it controls the
-way the highlight is drawn when one of a tree's children is selected.
-If it's GTK_TREE_VIEW_LINE, the entire GtkTreeItem widget is
-highlighted, while for GTK_TREE_VIEW_ITEM, only the child widget
-(i.e. usually the label) is highlighted.
-
-<tscreen><verb>
-void gtk_tree_set_view_lines( GtkTree *tree,
-                              guint    flag );
-</verb></tscreen>
-
-Controls whether connecting lines between tree items are drawn.
-<tt>flag</tt> is either TRUE, in which case they are, or FALSE, in
-which case they aren't.
-
-<tscreen><verb>
-GtkTree *GTK_TREE (gpointer obj);
-</verb></tscreen>
-
-Cast a generic pointer to `GtkTree *'.
-
-<tscreen><verb>
-GtkTreeClass *GTK_TREE_CLASS (gpointer class);
-</verb></tscreen>
-
-Cast a generic pointer to `GtkTreeClass*'.
-
-<tscreen><verb>
-gint GTK_IS_TREE (gpointer obj);
-</verb></tscreen>
-
-Determine if a generic pointer refers to a `GtkTree' object.
-
-<tscreen><verb>
-gint GTK_IS_ROOT_TREE (gpointer obj)
-</verb></tscreen>
-
-Determine if a generic pointer refers to a `GtkTree' object
-<em>and</em> is a root tree. Though this will accept any pointer, the
-results of passing it a pointer that does not refer to a GtkTree are
-undefined and possibly harmful.
-
-<tscreen><verb>
-GtkTree *GTK_TREE_ROOT_TREE (gpointer obj)
-</verb></tscreen>
-
-Return the root tree of a pointer to a `GtkTree' object. The above
-warning applies.
-
-<tscreen><verb>
-GList *GTK_TREE_SELECTION( gpointer obj)
-</verb></tscreen>
-
-Return the selection list of the root tree of a `GtkTree' object. The
-above warning applies here, too.
-
-<sect1> Tree Item Widget<label id="sec_Tree_Item_Widget">
-<p>
-The GtkTreeItem widget, like GtkListItem, is derived from GtkItem,
-which in turn is derived from GtkBin.  Therefore, the item itself is a
-generic container holding exactly one child widget, which can be of
-any type.  The GtkTreeItem widget has a number of extra fields, but
-the only one we need be concerned with is the <tt>subtree</tt> field.
-
-The definition for the GtkTreeItem struct looks like this:
-
-<tscreen><verb>
-struct _GtkTreeItem
-{
-  GtkItem item;
-
-  GtkWidget *subtree;
-  GtkWidget *pixmaps_box;
-  GtkWidget *plus_pix_widget, *minus_pix_widget;
-
-  GList *pixmaps;              /* pixmap node for this items color depth */
-
-  guint expanded : 1;
-};
-</verb></tscreen>
-
-The <tt>pixmaps_box</tt> field is a GtkEventBox which catches clicks
-on the plus/minus symbol which controls expansion and collapsing.  The
-<tt>pixmaps</tt> field points to an internal data structure.  Since
-you can always obtain the subtree of a GtkTreeItem in a (relatively)
-type-safe manner with the GTK_TREE_ITEM_SUBTREE (Item) macro, it's
-probably advisable never to touch the insides of a GtkTreeItem unless
-you <em>really</em> know what you're doing.
-
-Since it is directly derived from a GtkItem it can be treated as such
-by using the GTK_ITEM (TreeItem) macro. A GtkTreeItem usually holds a
-label, so the convenience function gtk_list_item_new_with_label() is
-provided. The same effect can be achieved using code like the
-following, which is actually copied verbatim from
-gtk_tree_item_new_with_label():
-
-<tscreen><verb>
-tree_item = gtk_tree_item_new ();
-label_widget = gtk_label_new (label);
-gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
-
-gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
-gtk_widget_show (label_widget);
-</verb></tscreen>
-
-As one is not forced to add a GtkLabel to a GtkTreeItem, you could
-also add a GtkHBox or a GtkArrow, or even a GtkNotebook (though your
-app will likely be quite unpopular in this case) to the GtkTreeItem.
+As one is not forced to add a GtkLabel to a GtkTreeItem, you could
+also add a GtkHBox or a GtkArrow, or even a GtkNotebook (though your
+app will likely be quite unpopular in this case) to the GtkTreeItem.
 
 If you remove all the items from a subtree, it will be destroyed and
 unparented, unless you reference it beforehand, and the GtkTreeItem
@@ -9139,12 +8748,6 @@ from your time.
 <sect1> Drawing Area
 <p>
 <!-- ----------------------------------------------------------------- -->
-<sect1> Fixed Container
-<p>
-<!-- ----------------------------------------------------------------- -->
-<sect1> Frame
-<p>
-<!-- ----------------------------------------------------------------- -->
 <sect1> Font Selection Dialog
 <p>
 <!-- ----------------------------------------------------------------- -->
@@ -14188,283 +13791,574 @@ The other event type that is different from the others is
 data types, which allows it to be cast to a specific
 event data type within a signal handler.
 
-<!-- Just a big list for now, needs expanding upon - TRG -->
-So, the event data types are defined as follows:
+<!-- Just a big list for now, needs expanding upon - TRG -->
+So, the event data types are defined as follows:
+
+<tscreen><verb>
+struct _GdkEventAny
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+};
+
+struct _GdkEventExpose
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkRectangle area;
+  gint count; /* If non-zero, how many more events follow. */
+};
+
+struct _GdkEventNoExpose
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  /* XXX: does anyone need the X major_code or minor_code fields? */
+};
+
+struct _GdkEventVisibility
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkVisibilityState state;
+};
+
+struct _GdkEventMotion
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+  guint state;
+  gint16 is_hint;
+  GdkInputSource source;
+  guint32 deviceid;
+  gdouble x_root, y_root;
+};
+
+struct _GdkEventButton
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+  guint state;
+  guint button;
+  GdkInputSource source;
+  guint32 deviceid;
+  gdouble x_root, y_root;
+};
+
+struct _GdkEventKey
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  guint state;
+  guint keyval;
+  gint length;
+  gchar *string;
+};
+
+struct _GdkEventCrossing
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkWindow *subwindow;
+  GdkNotifyType detail;
+};
+
+struct _GdkEventFocus
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  gint16 in;
+};
+
+struct _GdkEventConfigure
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  gint16 x, y;
+  gint16 width;
+  gint16 height;
+};
+
+struct _GdkEventProperty
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkAtom atom;
+  guint32 time;
+  guint state;
+};
+
+struct _GdkEventSelection
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkAtom selection;
+  GdkAtom target;
+  GdkAtom property;
+  guint32 requestor;
+  guint32 time;
+};
+
+/* This event type will be used pretty rarely. It only is important
+   for XInput aware programs that are drawing their own cursor */
+
+struct _GdkEventProximity
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  GdkInputSource source;
+  guint32 deviceid;
+};
+
+struct _GdkEventDragRequest
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint sendreply:1;
+      guint willaccept:1;
+      guint delete_data:1; /* Do *not* delete if link is sent, only
+                              if data is sent */
+      guint senddata:1;
+      guint reserved:22;
+    } flags;
+    glong allflags;
+  } u;
+  guint8 isdrop; /* This gdk event can be generated by a couple of
+                    X events - this lets the app know whether the
+                    drop really occurred or we just set the data */
+
+  GdkPoint drop_coords;
+  gchar *data_type;
+  guint32 timestamp;
+};
 
-<tscreen><verb>
-struct _GdkEventAny
+struct _GdkEventDragBegin
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint reserved:28;
+    } flags;
+    glong allflags;
+  } u;
 };
 
-struct _GdkEventExpose
+struct _GdkEventDropEnter
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  GdkRectangle area;
-  gint count; /* If non-zero, how many more events follow. */
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint sendreply:1;
+      guint extended_typelist:1;
+      guint reserved:26;
+    } flags;
+    glong allflags;
+  } u;
 };
 
-struct _GdkEventNoExpose
+struct _GdkEventDropLeave
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  /* XXX: does anyone need the X major_code or minor_code fields? */
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint reserved:28;
+    } flags;
+    glong allflags;
+  } u;
 };
 
-struct _GdkEventVisibility
+struct _GdkEventDropDataAvailable
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  GdkVisibilityState state;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint isdrop:1;
+      guint reserved:25;
+    } flags;
+    glong allflags;
+  } u;
+  gchar *data_type; /* MIME type */
+  gulong data_numbytes;
+  gpointer data;
+  guint32 timestamp;
+  GdkPoint coords;
 };
 
-struct _GdkEventMotion
+struct _GdkEventClient
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  guint32 time;
-  gdouble x;
-  gdouble y;
-  gdouble pressure;
-  gdouble xtilt;
-  gdouble ytilt;
-  guint state;
-  gint16 is_hint;
-  GdkInputSource source;
-  guint32 deviceid;
-  gdouble x_root, y_root;
+  GdkAtom message_type;
+  gushort data_format;
+  union {
+    char b[20];
+    short s[10];
+    long l[5];
+  } data;
 };
 
-struct _GdkEventButton
+struct _GdkEventOther
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  guint32 time;
-  gdouble x;
-  gdouble y;
-  gdouble pressure;
-  gdouble xtilt;
-  gdouble ytilt;
-  guint state;
-  guint button;
-  GdkInputSource source;
-  guint32 deviceid;
-  gdouble x_root, y_root;
+  GdkXEvent *xevent;
+};
+</verb></tscreen>
+
+<!-- ***************************************************************** -->
+<sect> Code Examples
+<!-- ***************************************************************** -->
+<p>
+Below are the code examples that are used in the above text
+which are not included in complete form elsewhere.
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Tictactoe
+<!-- ----------------------------------------------------------------- -->
+<sect2>tictactoe.h
+<p>
+<tscreen><verb>
+/* example-start tictactoe tictactoe.h */
+
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __TICTACTOE_H__
+#define __TICTACTOE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkvbox.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define TICTACTOE(obj)          GTK_CHECK_CAST (obj, tictactoe_get_type (), Tictactoe)
+#define TICTACTOE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, tictactoe_get_type (), TictactoeClass)
+#define IS_TICTACTOE(obj)       GTK_CHECK_TYPE (obj, tictactoe_get_type ())
+
+
+typedef struct _Tictactoe       Tictactoe;
+typedef struct _TictactoeClass  TictactoeClass;
+
+struct _Tictactoe
+{
+  GtkVBox vbox;
+  
+  GtkWidget *buttons[3][3];
+};
+
+struct _TictactoeClass
+{
+  GtkVBoxClass parent_class;
+
+  void (* tictactoe) (Tictactoe *ttt);
+};
+
+guint          tictactoe_get_type        (void);
+GtkWidget*     tictactoe_new             (void);
+void          tictactoe_clear           (Tictactoe *ttt);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TICTACTOE_H__ */
+
+/* example-end */
+</verb></tscreen>
+
+<!-- ----------------------------------------------------------------- -->
+<sect2>tictactoe.c
+<p>
+<tscreen><verb>
+/* example-start tictactoe tictactoe.c */
+
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "gtk/gtksignal.h"
+#include "gtk/gtktable.h"
+#include "gtk/gtktogglebutton.h"
+#include "tictactoe.h"
+
+enum {
+  TICTACTOE_SIGNAL,
+  LAST_SIGNAL
 };
 
-struct _GdkEventKey
+static void tictactoe_class_init          (TictactoeClass *klass);
+static void tictactoe_init                (Tictactoe      *ttt);
+static void tictactoe_toggle              (GtkWidget *widget, Tictactoe *ttt);
+
+static gint tictactoe_signals[LAST_SIGNAL] = { 0 };
+
+guint
+tictactoe_get_type ()
+{
+  static guint ttt_type = 0;
+
+  if (!ttt_type)
+    {
+      GtkTypeInfo ttt_info =
+      {
+       "Tictactoe",
+       sizeof (Tictactoe),
+       sizeof (TictactoeClass),
+       (GtkClassInitFunc) tictactoe_class_init,
+       (GtkObjectInitFunc) tictactoe_init,
+        (GtkArgSetFunc) NULL,
+        (GtkArgGetFunc) NULL
+      };
+
+      ttt_type = gtk_type_unique (gtk_vbox_get_type (), &amp;ttt_info);
+    }
+
+  return ttt_type;
+}
+
+static void
+tictactoe_class_init (TictactoeClass *class)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 time;
-  guint state;
-  guint keyval;
-  gint length;
-  gchar *string;
-};
+  GtkObjectClass *object_class;
 
-struct _GdkEventCrossing
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkWindow *subwindow;
-  GdkNotifyType detail;
-};
+  object_class = (GtkObjectClass*) class;
+  
+  tictactoe_signals[TICTACTOE_SIGNAL] = gtk_signal_new ("tictactoe",
+                                        GTK_RUN_FIRST,
+                                        object_class->type,
+                                        GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
+                                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
 
-struct _GdkEventFocus
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  gint16 in;
-};
 
-struct _GdkEventConfigure
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  gint16 x, y;
-  gint16 width;
-  gint16 height;
-};
+  gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
 
-struct _GdkEventProperty
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkAtom atom;
-  guint32 time;
-  guint state;
-};
+  class->tictactoe = NULL;
+}
 
-struct _GdkEventSelection
+static void
+tictactoe_init (Tictactoe *ttt)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkAtom selection;
-  GdkAtom target;
-  GdkAtom property;
-  guint32 requestor;
-  guint32 time;
-};
+  GtkWidget *table;
+  gint i,j;
+  
+  table = gtk_table_new (3, 3, TRUE);
+  gtk_container_add (GTK_CONTAINER(ttt), table);
+  gtk_widget_show (table);
 
-/* This event type will be used pretty rarely. It only is important
-   for XInput aware programs that are drawing their own cursor */
+  for (i=0;i<3; i++)
+    for (j=0;j<3; j++)
+      {
+       ttt->buttons[i][j] = gtk_toggle_button_new ();
+       gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j], 
+                                  i, i+1, j, j+1);
+       gtk_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
+                           GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
+       gtk_widget_set_usize (ttt->buttons[i][j], 20, 20);
+       gtk_widget_show (ttt->buttons[i][j]);
+      }
+}
 
-struct _GdkEventProximity
+GtkWidget*
+tictactoe_new ()
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 time;
-  GdkInputSource source;
-  guint32 deviceid;
-};
+  return GTK_WIDGET ( gtk_type_new (tictactoe_get_type ()));
+}
 
-struct _GdkEventDragRequest
+void          
+tictactoe_clear (Tictactoe *ttt)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint sendreply:1;
-      guint willaccept:1;
-      guint delete_data:1; /* Do *not* delete if link is sent, only
-                              if data is sent */
-      guint senddata:1;
-      guint reserved:22;
-    } flags;
-    glong allflags;
-  } u;
-  guint8 isdrop; /* This gdk event can be generated by a couple of
-                    X events - this lets the app know whether the
-                    drop really occurred or we just set the data */
+  int i,j;
 
-  GdkPoint drop_coords;
-  gchar *data_type;
-  guint32 timestamp;
-};
+  for (i=0;i<3;i++)
+    for (j=0;j<3;j++)
+      {
+       gtk_signal_handler_block_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
+                                    FALSE);
+       gtk_signal_handler_unblock_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
+      }
+}
 
-struct _GdkEventDragBegin
+static void
+tictactoe_toggle (GtkWidget *widget, Tictactoe *ttt)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint reserved:28;
-    } flags;
-    glong allflags;
-  } u;
-};
+  int i,k;
 
-struct _GdkEventDropEnter
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint sendreply:1;
-      guint extended_typelist:1;
-      guint reserved:26;
-    } flags;
-    glong allflags;
-  } u;
-};
+  static int rwins[8][3] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
+                            { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
+                            { 0, 1, 2 }, { 0, 1, 2 } };
+  static int cwins[8][3] = { { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
+                            { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
+                            { 0, 1, 2 }, { 2, 1, 0 } };
 
-struct _GdkEventDropLeave
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint reserved:28;
-    } flags;
-    glong allflags;
-  } u;
-};
+  int success, found;
 
-struct _GdkEventDropDataAvailable
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint isdrop:1;
-      guint reserved:25;
-    } flags;
-    glong allflags;
-  } u;
-  gchar *data_type; /* MIME type */
-  gulong data_numbytes;
-  gpointer data;
-  guint32 timestamp;
-  GdkPoint coords;
-};
+  for (k=0; k<8; k++)
+    {
+      success = TRUE;
+      found = FALSE;
 
-struct _GdkEventClient
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkAtom message_type;
-  gushort data_format;
-  union {
-    char b[20];
-    short s[10];
-    long l[5];
-  } data;
-};
+      for (i=0;i<3;i++)
+       {
+         success = success &amp;&amp; 
+           GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
+         found = found ||
+           ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
+       }
+      
+      if (success &amp;&amp; found)
+       {
+         gtk_signal_emit (GTK_OBJECT (ttt), 
+                          tictactoe_signals[TICTACTOE_SIGNAL]);
+         break;
+       }
+    }
+}
+
+/* example-end */
+</verb></tscreen>
+
+<!-- ----------------------------------------------------------------- -->
+<sect2>ttt_test.c
+<p>
+<tscreen><verb>
+/* example-start tictactoe ttt_test.c */
+
+#include <gtk/gtk.h>
+#include "tictactoe.h"
+
+void
+win (GtkWidget *widget, gpointer data)
+{
+  g_print ("Yay!\n");
+  tictactoe_clear (TICTACTOE (widget));
+}
 
-struct _GdkEventOther
+int 
+main (int argc, char *argv[])
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkXEvent *xevent;
-};
-</verb></tscreen>
+  GtkWidget *window;
+  GtkWidget *ttt;
+  
+  gtk_init (&amp;argc, &amp;argv);
 
-<!-- ***************************************************************** -->
-<sect> Code Examples
-<!-- ***************************************************************** -->
-<p>
-Below are the code examples that are used in the above text
-which are not included in complete form elsewhere.
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  
+  gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
+  
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (gtk_exit), NULL);
+  
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+  ttt = tictactoe_new ();
+  
+  gtk_container_add (GTK_CONTAINER (window), ttt);
+  gtk_widget_show (ttt);
+
+  gtk_signal_connect (GTK_OBJECT (ttt), "tictactoe",
+                     GTK_SIGNAL_FUNC (win), NULL);
+
+  gtk_widget_show (window);
+  
+  gtk_main ();
+  
+  return 0;
+}
+
+/* example-end */
+</verb></tscreen>
 
 <!-- ----------------------------------------------------------------- -->
-<sect1>Tictactoe
+<sect1> GtkDial
+
 <!-- ----------------------------------------------------------------- -->
-<sect2>tictactoe.h
+<sect2> gtkdial.h
 <p>
 <tscreen><verb>
-/* example-start tictactoe tictactoe.h */
+/* example-start gtkdial gtkdial.h */
 
 /* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
@@ -14484,58 +14378,85 @@ which are not included in complete form elsewhere.
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#ifndef __TICTACTOE_H__
-#define __TICTACTOE_H__
+#ifndef __GTK_DIAL_H__
+#define __GTK_DIAL_H__
 
 
 #include <gdk/gdk.h>
-#include <gtk/gtkvbox.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-#define TICTACTOE(obj)          GTK_CHECK_CAST (obj, tictactoe_get_type (), Tictactoe)
-#define TICTACTOE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, tictactoe_get_type (), TictactoeClass)
-#define IS_TICTACTOE(obj)       GTK_CHECK_TYPE (obj, tictactoe_get_type ())
 
+#define GTK_DIAL(obj)          GTK_CHECK_CAST (obj, gtk_dial_get_type (), GtkDial)
+#define GTK_DIAL_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_dial_get_type (), GtkDialClass)
+#define GTK_IS_DIAL(obj)       GTK_CHECK_TYPE (obj, gtk_dial_get_type ())
 
-typedef struct _Tictactoe       Tictactoe;
-typedef struct _TictactoeClass  TictactoeClass;
 
-struct _Tictactoe
+typedef struct _GtkDial        GtkDial;
+typedef struct _GtkDialClass   GtkDialClass;
+
+struct _GtkDial
 {
-  GtkVBox vbox;
-  
-  GtkWidget *buttons[3][3];
+  GtkWidget widget;
+
+  /* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
+  guint policy : 2;
+
+  /* Button currently pressed or 0 if none */
+  guint8 button;
+
+  /* Dimensions of dial components */
+  gint radius;
+  gint pointer_width;
+
+  /* ID of update timer, or 0 if none */
+  guint32 timer;
+
+  /* Current angle */
+  gfloat angle;
+
+  /* Old values from adjustment stored so we know when something changes */
+  gfloat old_value;
+  gfloat old_lower;
+  gfloat old_upper;
+
+  /* The adjustment object that stores the data for this dial */
+  GtkAdjustment *adjustment;
 };
 
-struct _TictactoeClass
+struct _GtkDialClass
 {
-  GtkVBoxClass parent_class;
-
-  void (* tictactoe) (Tictactoe *ttt);
+  GtkWidgetClass parent_class;
 };
 
-guint          tictactoe_get_type        (void);
-GtkWidget*     tictactoe_new             (void);
-void          tictactoe_clear           (Tictactoe *ttt);
 
+GtkWidget*     gtk_dial_new                    (GtkAdjustment *adjustment);
+guint          gtk_dial_get_type               (void);
+GtkAdjustment* gtk_dial_get_adjustment         (GtkDial      *dial);
+void           gtk_dial_set_update_policy      (GtkDial      *dial,
+                                               GtkUpdateType  policy);
+
+void           gtk_dial_set_adjustment         (GtkDial      *dial,
+                                               GtkAdjustment *adjustment);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* __TICTACTOE_H__ */
 
+#endif /* __GTK_DIAL_H__ */
 /* example-end */
 </verb></tscreen>
 
 <!-- ----------------------------------------------------------------- -->
-<sect2>tictactoe.c
+<sect2> gtkdial.c
 <p>
 <tscreen><verb>
-/* example-start tictactoe tictactoe.c */
+/* example-start gtkdial gtkdial.c */
 
 /* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
@@ -14555,1082 +14476,1379 @@ void             tictactoe_clear           (Tictactoe *ttt);
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include "gtk/gtksignal.h"
-#include "gtk/gtktable.h"
-#include "gtk/gtktogglebutton.h"
-#include "tictactoe.h"
+#include <math.h>
+#include <stdio.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtksignal.h>
 
-enum {
-  TICTACTOE_SIGNAL,
-  LAST_SIGNAL
-};
+#include "gtkdial.h"
 
-static void tictactoe_class_init          (TictactoeClass *klass);
-static void tictactoe_init                (Tictactoe      *ttt);
-static void tictactoe_toggle              (GtkWidget *widget, Tictactoe *ttt);
+#define SCROLL_DELAY_LENGTH  300
+#define DIAL_DEFAULT_SIZE 100
 
-static gint tictactoe_signals[LAST_SIGNAL] = { 0 };
+/* Forward declarations */
+
+static void gtk_dial_class_init               (GtkDialClass    *klass);
+static void gtk_dial_init                     (GtkDial         *dial);
+static void gtk_dial_destroy                  (GtkObject        *object);
+static void gtk_dial_realize                  (GtkWidget        *widget);
+static void gtk_dial_size_request             (GtkWidget      *widget,
+                                              GtkRequisition *requisition);
+static void gtk_dial_size_allocate            (GtkWidget     *widget,
+                                              GtkAllocation *allocation);
+static gint gtk_dial_expose                   (GtkWidget        *widget,
+                                               GdkEventExpose   *event);
+static gint gtk_dial_button_press             (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gint gtk_dial_button_release           (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gint gtk_dial_motion_notify            (GtkWidget        *widget,
+                                               GdkEventMotion   *event);
+static gint gtk_dial_timer                    (GtkDial         *dial);
+
+static void gtk_dial_update_mouse             (GtkDial *dial, gint x, gint y);
+static void gtk_dial_update                   (GtkDial *dial);
+static void gtk_dial_adjustment_changed       (GtkAdjustment    *adjustment,
+                                               gpointer          data);
+static void gtk_dial_adjustment_value_changed (GtkAdjustment    *adjustment,
+                                               gpointer          data);
+
+/* Local data */
+
+static GtkWidgetClass *parent_class = NULL;
 
 guint
-tictactoe_get_type ()
+gtk_dial_get_type ()
 {
-  static guint ttt_type = 0;
+  static guint dial_type = 0;
 
-  if (!ttt_type)
+  if (!dial_type)
     {
-      GtkTypeInfo ttt_info =
+      GtkTypeInfo dial_info =
       {
-       "Tictactoe",
-       sizeof (Tictactoe),
-       sizeof (TictactoeClass),
-       (GtkClassInitFunc) tictactoe_class_init,
-       (GtkObjectInitFunc) tictactoe_init,
-        (GtkArgSetFunc) NULL,
-        (GtkArgGetFunc) NULL
+       "GtkDial",
+       sizeof (GtkDial),
+       sizeof (GtkDialClass),
+       (GtkClassInitFunc) gtk_dial_class_init,
+       (GtkObjectInitFunc) gtk_dial_init,
+       (GtkArgSetFunc) NULL,
+       (GtkArgGetFunc) NULL,
       };
 
-      ttt_type = gtk_type_unique (gtk_vbox_get_type (), &amp;ttt_info);
+      dial_type = gtk_type_unique (gtk_widget_get_type (), &amp;dial_info);
     }
 
-  return ttt_type;
+  return dial_type;
 }
 
 static void
-tictactoe_class_init (TictactoeClass *class)
+gtk_dial_class_init (GtkDialClass *class)
 {
   GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+
+  object_class->destroy = gtk_dial_destroy;
+
+  widget_class->realize = gtk_dial_realize;
+  widget_class->expose_event = gtk_dial_expose;
+  widget_class->size_request = gtk_dial_size_request;
+  widget_class->size_allocate = gtk_dial_size_allocate;
+  widget_class->button_press_event = gtk_dial_button_press;
+  widget_class->button_release_event = gtk_dial_button_release;
+  widget_class->motion_notify_event = gtk_dial_motion_notify;
+}
+
+static void
+gtk_dial_init (GtkDial *dial)
+{
+  dial->button = 0;
+  dial->policy = GTK_UPDATE_CONTINUOUS;
+  dial->timer = 0;
+  dial->radius = 0;
+  dial->pointer_width = 0;
+  dial->angle = 0.0;
+  dial->old_value = 0.0;
+  dial->old_lower = 0.0;
+  dial->old_upper = 0.0;
+  dial->adjustment = NULL;
+}
+
+GtkWidget*
+gtk_dial_new (GtkAdjustment *adjustment)
+{
+  GtkDial *dial;
+
+  dial = gtk_type_new (gtk_dial_get_type ());
+
+  if (!adjustment)
+    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_dial_set_adjustment (dial, adjustment);
+
+  return GTK_WIDGET (dial);
+}
+
+static void
+gtk_dial_destroy (GtkObject *object)
+{
+  GtkDial *dial;
 
-  object_class = (GtkObjectClass*) class;
-  
-  tictactoe_signals[TICTACTOE_SIGNAL] = gtk_signal_new ("tictactoe",
-                                        GTK_RUN_FIRST,
-                                        object_class->type,
-                                        GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
-                                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_DIAL (object));
 
+  dial = GTK_DIAL (object);
 
-  gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
+  if (dial->adjustment)
+    gtk_object_unref (GTK_OBJECT (dial->adjustment));
 
-  class->tictactoe = NULL;
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
-static void
-tictactoe_init (Tictactoe *ttt)
+GtkAdjustment*
+gtk_dial_get_adjustment (GtkDial *dial)
 {
-  GtkWidget *table;
-  gint i,j;
-  
-  table = gtk_table_new (3, 3, TRUE);
-  gtk_container_add (GTK_CONTAINER(ttt), table);
-  gtk_widget_show (table);
+  g_return_val_if_fail (dial != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);
 
-  for (i=0;i<3; i++)
-    for (j=0;j<3; j++)
-      {
-       ttt->buttons[i][j] = gtk_toggle_button_new ();
-       gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j], 
-                                  i, i+1, j, j+1);
-       gtk_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
-                           GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
-       gtk_widget_set_usize (ttt->buttons[i][j], 20, 20);
-       gtk_widget_show (ttt->buttons[i][j]);
-      }
+  return dial->adjustment;
 }
 
-GtkWidget*
-tictactoe_new ()
+void
+gtk_dial_set_update_policy (GtkDial      *dial,
+                            GtkUpdateType  policy)
 {
-  return GTK_WIDGET ( gtk_type_new (tictactoe_get_type ()));
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  dial->policy = policy;
 }
 
-void          
-tictactoe_clear (Tictactoe *ttt)
+void
+gtk_dial_set_adjustment (GtkDial      *dial,
+                         GtkAdjustment *adjustment)
 {
-  int i,j;
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
 
-  for (i=0;i<3;i++)
-    for (j=0;j<3;j++)
-      {
-       gtk_signal_handler_block_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
-       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
-                                    FALSE);
-       gtk_signal_handler_unblock_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
-      }
+  if (dial->adjustment)
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), (gpointer) dial);
+      gtk_object_unref (GTK_OBJECT (dial->adjustment));
+    }
+
+  dial->adjustment = adjustment;
+  gtk_object_ref (GTK_OBJECT (dial->adjustment));
+
+  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
+                     (GtkSignalFunc) gtk_dial_adjustment_changed,
+                     (gpointer) dial);
+  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                     (GtkSignalFunc) gtk_dial_adjustment_value_changed,
+                     (gpointer) dial);
+
+  dial->old_value = adjustment->value;
+  dial->old_lower = adjustment->lower;
+  dial->old_upper = adjustment->upper;
+
+  gtk_dial_update (dial);
 }
 
 static void
-tictactoe_toggle (GtkWidget *widget, Tictactoe *ttt)
+gtk_dial_realize (GtkWidget *widget)
 {
-  int i,k;
+  GtkDial *dial;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
 
-  static int rwins[8][3] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
-                            { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
-                            { 0, 1, 2 }, { 0, 1, 2 } };
-  static int cwins[8][3] = { { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
-                            { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
-                            { 0, 1, 2 }, { 2, 1, 0 } };
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DIAL (widget));
 
-  int success, found;
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  dial = GTK_DIAL (widget);
 
-  for (k=0; k<8; k++)
-    {
-      success = TRUE;
-      found = FALSE;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask = gtk_widget_get_events (widget) | 
+    GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+    GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+    GDK_POINTER_MOTION_HINT_MASK;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
 
-      for (i=0;i<3;i++)
-       {
-         success = success &amp;&amp; 
-           GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
-         found = found ||
-           ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
-       }
-      
-      if (success &amp;&amp; found)
-       {
-         gtk_signal_emit (GTK_OBJECT (ttt), 
-                          tictactoe_signals[TICTACTOE_SIGNAL]);
-         break;
-       }
-    }
-}
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &amp;attributes, attributes_mask);
 
-/* example-end */
-</verb></tscreen>
+  widget->style = gtk_style_attach (widget->style, widget->window);
 
-<!-- ----------------------------------------------------------------- -->
-<sect2>ttt_test.c
-<p>
-<tscreen><verb>
-/* example-start tictactoe ttt_test.c */
+  gdk_window_set_user_data (widget->window, widget);
 
-#include <gtk/gtk.h>
-#include "tictactoe.h"
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+}
 
-void
-win (GtkWidget *widget, gpointer data)
+static void 
+gtk_dial_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
 {
-  g_print ("Yay!\n");
-  tictactoe_clear (TICTACTOE (widget));
+  requisition->width = DIAL_DEFAULT_SIZE;
+  requisition->height = DIAL_DEFAULT_SIZE;
 }
 
-int 
-main (int argc, char *argv[])
+static void
+gtk_dial_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
 {
-  GtkWidget *window;
-  GtkWidget *ttt;
-  
-  gtk_init (&amp;argc, &amp;argv);
+  GtkDial *dial;
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  
-  gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
-  
-  gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                     GTK_SIGNAL_FUNC (gtk_exit), NULL);
-  
-  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DIAL (widget));
+  g_return_if_fail (allocation != NULL);
 
-  ttt = tictactoe_new ();
-  
-  gtk_container_add (GTK_CONTAINER (window), ttt);
-  gtk_widget_show (ttt);
+  widget->allocation = *allocation;
+  dial = GTK_DIAL (widget);
 
-  gtk_signal_connect (GTK_OBJECT (ttt), "tictactoe",
-                     GTK_SIGNAL_FUNC (win), NULL);
+  if (GTK_WIDGET_REALIZED (widget))
+    {
 
-  gtk_widget_show (window);
-  
-  gtk_main ();
-  
-  return 0;
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+    }
+  dial->radius = MIN(allocation->width,allocation->height) * 0.45;
+  dial->pointer_width = dial->radius / 5;
 }
 
-/* example-end */
-</verb></tscreen>
+static gint
+gtk_dial_expose (GtkWidget      *widget,
+                GdkEventExpose *event)
+{
+  GtkDial *dial;
+  GdkPoint points[3];
+  gdouble s,c;
+  gdouble theta;
+  gint xc, yc;
+  gint tick_length;
+  gint i;
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> GtkDial
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-<!-- ----------------------------------------------------------------- -->
-<sect2> gtkdial.h
-<p>
-<tscreen><verb>
-/* example-start gtkdial gtkdial.h */
+  if (event->count > 0)
+    return FALSE;
+  
+  dial = GTK_DIAL (widget);
 
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __GTK_DIAL_H__
-#define __GTK_DIAL_H__
+  gdk_window_clear_area (widget->window,
+                        0, 0,
+                        widget->allocation.width,
+                        widget->allocation.height);
+
+  xc = widget->allocation.width/2;
+  yc = widget->allocation.height/2;
 
+  /* Draw ticks */
 
-#include <gdk/gdk.h>
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtkwidget.h>
+  for (i=0; i<25; i++)
+    {
+      theta = (i*M_PI/18. - M_PI/6.);
+      s = sin(theta);
+      c = cos(theta);
 
+      tick_length = (i%6 == 0) ? dial->pointer_width : dial->pointer_width/2;
+      
+      gdk_draw_line (widget->window,
+                    widget->style->fg_gc[widget->state],
+                    xc + c*(dial->radius - tick_length),
+                    yc - s*(dial->radius - tick_length),
+                    xc + c*dial->radius,
+                    yc - s*dial->radius);
+    }
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+  /* Draw pointer */
 
+  s = sin(dial->angle);
+  c = cos(dial->angle);
 
-#define GTK_DIAL(obj)          GTK_CHECK_CAST (obj, gtk_dial_get_type (), GtkDial)
-#define GTK_DIAL_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_dial_get_type (), GtkDialClass)
-#define GTK_IS_DIAL(obj)       GTK_CHECK_TYPE (obj, gtk_dial_get_type ())
 
+  points[0].x = xc + s*dial->pointer_width/2;
+  points[0].y = yc + c*dial->pointer_width/2;
+  points[1].x = xc + c*dial->radius;
+  points[1].y = yc - s*dial->radius;
+  points[2].x = xc - s*dial->pointer_width/2;
+  points[2].y = yc - c*dial->pointer_width/2;
 
-typedef struct _GtkDial        GtkDial;
-typedef struct _GtkDialClass   GtkDialClass;
+  gtk_draw_polygon (widget->style,
+                   widget->window,
+                   GTK_STATE_NORMAL,
+                   GTK_SHADOW_OUT,
+                   points, 3,
+                   TRUE);
+  
+  return FALSE;
+}
 
-struct _GtkDial
+static gint
+gtk_dial_button_press (GtkWidget      *widget,
+                      GdkEventButton *event)
 {
-  GtkWidget widget;
-
-  /* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
-  guint policy : 2;
+  GtkDial *dial;
+  gint dx, dy;
+  double s, c;
+  double d_parallel;
+  double d_perpendicular;
 
-  /* Button currently pressed or 0 if none */
-  guint8 button;
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-  /* Dimensions of dial components */
-  gint radius;
-  gint pointer_width;
+  dial = GTK_DIAL (widget);
 
-  /* ID of update timer, or 0 if none */
-  guint32 timer;
+  /* Determine if button press was within pointer region - we 
+     do this by computing the parallel and perpendicular distance of
+     the point where the mouse was pressed from the line passing through
+     the pointer */
+  
+  dx = event->x - widget->allocation.width / 2;
+  dy = widget->allocation.height / 2 - event->y;
+  
+  s = sin(dial->angle);
+  c = cos(dial->angle);
+  
+  d_parallel = s*dy + c*dx;
+  d_perpendicular = fabs(s*dx - c*dy);
+  
+  if (!dial->button &amp;&amp;
+      (d_perpendicular < dial->pointer_width/2) &amp;&amp;
+      (d_parallel > - dial->pointer_width))
+    {
+      gtk_grab_add (widget);
 
-  /* Current angle */
-  gfloat angle;
+      dial->button = event->button;
 
-  /* Old values from adjustment stored so we know when something changes */
-  gfloat old_value;
-  gfloat old_lower;
-  gfloat old_upper;
+      gtk_dial_update_mouse (dial, event->x, event->y);
+    }
 
-  /* The adjustment object that stores the data for this dial */
-  GtkAdjustment *adjustment;
-};
+  return FALSE;
+}
 
-struct _GtkDialClass
+static gint
+gtk_dial_button_release (GtkWidget      *widget,
+                         GdkEventButton *event)
 {
-  GtkWidgetClass parent_class;
-};
+  GtkDial *dial;
 
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-GtkWidget*     gtk_dial_new                    (GtkAdjustment *adjustment);
-guint          gtk_dial_get_type               (void);
-GtkAdjustment* gtk_dial_get_adjustment         (GtkDial      *dial);
-void           gtk_dial_set_update_policy      (GtkDial      *dial,
-                                               GtkUpdateType  policy);
+  dial = GTK_DIAL (widget);
 
-void           gtk_dial_set_adjustment         (GtkDial      *dial,
-                                               GtkAdjustment *adjustment);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+  if (dial->button == event->button)
+    {
+      gtk_grab_remove (widget);
 
+      dial->button = 0;
 
-#endif /* __GTK_DIAL_H__ */
-/* example-end */
-</verb></tscreen>
+      if (dial->policy == GTK_UPDATE_DELAYED)
+       gtk_timeout_remove (dial->timer);
+      
+      if ((dial->policy != GTK_UPDATE_CONTINUOUS) &amp;&amp;
+         (dial->old_value != dial->adjustment->value))
+       gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    }
 
-<!-- ----------------------------------------------------------------- -->
-<sect2> gtkdial.c
-<p>
-<tscreen><verb>
-/* example-start gtkdial gtkdial.c */
+  return FALSE;
+}
 
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#include <math.h>
-#include <stdio.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
+static gint
+gtk_dial_motion_notify (GtkWidget      *widget,
+                        GdkEventMotion *event)
+{
+  GtkDial *dial;
+  GdkModifierType mods;
+  gint x, y, mask;
 
-#include "gtkdial.h"
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-#define SCROLL_DELAY_LENGTH  300
-#define DIAL_DEFAULT_SIZE 100
+  dial = GTK_DIAL (widget);
 
-/* Forward declarations */
+  if (dial->button != 0)
+    {
+      x = event->x;
+      y = event->y;
 
-static void gtk_dial_class_init               (GtkDialClass    *klass);
-static void gtk_dial_init                     (GtkDial         *dial);
-static void gtk_dial_destroy                  (GtkObject        *object);
-static void gtk_dial_realize                  (GtkWidget        *widget);
-static void gtk_dial_size_request             (GtkWidget      *widget,
-                                              GtkRequisition *requisition);
-static void gtk_dial_size_allocate            (GtkWidget     *widget,
-                                              GtkAllocation *allocation);
-static gint gtk_dial_expose                   (GtkWidget        *widget,
-                                               GdkEventExpose   *event);
-static gint gtk_dial_button_press             (GtkWidget        *widget,
-                                               GdkEventButton   *event);
-static gint gtk_dial_button_release           (GtkWidget        *widget,
-                                               GdkEventButton   *event);
-static gint gtk_dial_motion_notify            (GtkWidget        *widget,
-                                               GdkEventMotion   *event);
-static gint gtk_dial_timer                    (GtkDial         *dial);
+      if (event->is_hint || (event->window != widget->window))
+       gdk_window_get_pointer (widget->window, &amp;x, &amp;y, &amp;mods);
 
-static void gtk_dial_update_mouse             (GtkDial *dial, gint x, gint y);
-static void gtk_dial_update                   (GtkDial *dial);
-static void gtk_dial_adjustment_changed       (GtkAdjustment    *adjustment,
-                                               gpointer          data);
-static void gtk_dial_adjustment_value_changed (GtkAdjustment    *adjustment,
-                                               gpointer          data);
+      switch (dial->button)
+       {
+       case 1:
+         mask = GDK_BUTTON1_MASK;
+         break;
+       case 2:
+         mask = GDK_BUTTON2_MASK;
+         break;
+       case 3:
+         mask = GDK_BUTTON3_MASK;
+         break;
+       default:
+         mask = 0;
+         break;
+       }
 
-/* Local data */
+      if (mods &amp; mask)
+       gtk_dial_update_mouse (dial, x,y);
+    }
 
-static GtkWidgetClass *parent_class = NULL;
+  return FALSE;
+}
 
-guint
-gtk_dial_get_type ()
+static gint
+gtk_dial_timer (GtkDial *dial)
 {
-  static guint dial_type = 0;
-
-  if (!dial_type)
-    {
-      GtkTypeInfo dial_info =
-      {
-       "GtkDial",
-       sizeof (GtkDial),
-       sizeof (GtkDialClass),
-       (GtkClassInitFunc) gtk_dial_class_init,
-       (GtkObjectInitFunc) gtk_dial_init,
-       (GtkArgSetFunc) NULL,
-       (GtkArgGetFunc) NULL,
-      };
+  g_return_val_if_fail (dial != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
 
-      dial_type = gtk_type_unique (gtk_widget_get_type (), &amp;dial_info);
-    }
+  if (dial->policy == GTK_UPDATE_DELAYED)
+    gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
 
-  return dial_type;
+  return FALSE;
 }
 
 static void
-gtk_dial_class_init (GtkDialClass *class)
+gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
 {
-  GtkObjectClass *object_class;
-  GtkWidgetClass *widget_class;
+  gint xc, yc;
+  gfloat old_value;
 
-  object_class = (GtkObjectClass*) class;
-  widget_class = (GtkWidgetClass*) class;
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
 
-  parent_class = gtk_type_class (gtk_widget_get_type ());
+  xc = GTK_WIDGET(dial)->allocation.width / 2;
+  yc = GTK_WIDGET(dial)->allocation.height / 2;
 
-  object_class->destroy = gtk_dial_destroy;
+  old_value = dial->adjustment->value;
+  dial->angle = atan2(yc-y, x-xc);
 
-  widget_class->realize = gtk_dial_realize;
-  widget_class->expose_event = gtk_dial_expose;
-  widget_class->size_request = gtk_dial_size_request;
-  widget_class->size_allocate = gtk_dial_size_allocate;
-  widget_class->button_press_event = gtk_dial_button_press;
-  widget_class->button_release_event = gtk_dial_button_release;
-  widget_class->motion_notify_event = gtk_dial_motion_notify;
-}
+  if (dial->angle < -M_PI/2.)
+    dial->angle += 2*M_PI;
 
-static void
-gtk_dial_init (GtkDial *dial)
-{
-  dial->button = 0;
-  dial->policy = GTK_UPDATE_CONTINUOUS;
-  dial->timer = 0;
-  dial->radius = 0;
-  dial->pointer_width = 0;
-  dial->angle = 0.0;
-  dial->old_value = 0.0;
-  dial->old_lower = 0.0;
-  dial->old_upper = 0.0;
-  dial->adjustment = NULL;
-}
+  if (dial->angle < -M_PI/6)
+    dial->angle = -M_PI/6;
 
-GtkWidget*
-gtk_dial_new (GtkAdjustment *adjustment)
-{
-  GtkDial *dial;
+  if (dial->angle > 7.*M_PI/6.)
+    dial->angle = 7.*M_PI/6.;
 
-  dial = gtk_type_new (gtk_dial_get_type ());
+  dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
+    (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
 
-  if (!adjustment)
-    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+  if (dial->adjustment->value != old_value)
+    {
+      if (dial->policy == GTK_UPDATE_CONTINUOUS)
+       {
+         gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+       }
+      else
+       {
+         gtk_widget_draw (GTK_WIDGET(dial), NULL);
 
-  gtk_dial_set_adjustment (dial, adjustment);
+         if (dial->policy == GTK_UPDATE_DELAYED)
+           {
+             if (dial->timer)
+               gtk_timeout_remove (dial->timer);
 
-  return GTK_WIDGET (dial);
+             dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
+                                            (GtkFunction) gtk_dial_timer,
+                                            (gpointer) dial);
+           }
+       }
+    }
 }
 
 static void
-gtk_dial_destroy (GtkObject *object)
+gtk_dial_update (GtkDial *dial)
 {
-  GtkDial *dial;
-
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_DIAL (object));
+  gfloat new_value;
+  
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
 
-  dial = GTK_DIAL (object);
+  new_value = dial->adjustment->value;
+  
+  if (new_value < dial->adjustment->lower)
+    new_value = dial->adjustment->lower;
 
-  if (dial->adjustment)
-    gtk_object_unref (GTK_OBJECT (dial->adjustment));
+  if (new_value > dial->adjustment->upper)
+    new_value = dial->adjustment->upper;
 
-  if (GTK_OBJECT_CLASS (parent_class)->destroy)
-    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
+  if (new_value != dial->adjustment->value)
+    {
+      dial->adjustment->value = new_value;
+      gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    }
 
-GtkAdjustment*
-gtk_dial_get_adjustment (GtkDial *dial)
-{
-  g_return_val_if_fail (dial != NULL, NULL);
-  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);
+  dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
+    (dial->adjustment->upper - dial->adjustment->lower);
 
-  return dial->adjustment;
+  gtk_widget_draw (GTK_WIDGET(dial), NULL);
 }
 
-void
-gtk_dial_set_update_policy (GtkDial      *dial,
-                            GtkUpdateType  policy)
+static void
+gtk_dial_adjustment_changed (GtkAdjustment *adjustment,
+                             gpointer       data)
 {
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+  GtkDial *dial;
 
-  dial->policy = policy;
-}
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
 
-void
-gtk_dial_set_adjustment (GtkDial      *dial,
-                         GtkAdjustment *adjustment)
-{
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+  dial = GTK_DIAL (data);
 
-  if (dial->adjustment)
+  if ((dial->old_value != adjustment->value) ||
+      (dial->old_lower != adjustment->lower) ||
+      (dial->old_upper != adjustment->upper))
     {
-      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), (gpointer) dial);
-      gtk_object_unref (GTK_OBJECT (dial->adjustment));
-    }
-
-  dial->adjustment = adjustment;
-  gtk_object_ref (GTK_OBJECT (dial->adjustment));
-
-  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                     (GtkSignalFunc) gtk_dial_adjustment_changed,
-                     (gpointer) dial);
-  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                     (GtkSignalFunc) gtk_dial_adjustment_value_changed,
-                     (gpointer) dial);
-
-  dial->old_value = adjustment->value;
-  dial->old_lower = adjustment->lower;
-  dial->old_upper = adjustment->upper;
+      gtk_dial_update (dial);
 
-  gtk_dial_update (dial);
+      dial->old_value = adjustment->value;
+      dial->old_lower = adjustment->lower;
+      dial->old_upper = adjustment->upper;
+    }
 }
 
 static void
-gtk_dial_realize (GtkWidget *widget)
+gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
+                                   gpointer       data)
 {
   GtkDial *dial;
-  GdkWindowAttr attributes;
-  gint attributes_mask;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_DIAL (widget));
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
 
-  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-  dial = GTK_DIAL (widget);
+  dial = GTK_DIAL (data);
 
-  attributes.x = widget->allocation.x;
-  attributes.y = widget->allocation.y;
-  attributes.width = widget->allocation.width;
-  attributes.height = widget->allocation.height;
-  attributes.wclass = GDK_INPUT_OUTPUT;
-  attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.event_mask = gtk_widget_get_events (widget) | 
-    GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-    GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
-    GDK_POINTER_MOTION_HINT_MASK;
-  attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
+  if (dial->old_value != adjustment->value)
+    {
+      gtk_dial_update (dial);
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-  widget->window = gdk_window_new (widget->parent->window, &amp;attributes, attributes_mask);
+      dial->old_value = adjustment->value;
+    }
+}
+/* example-end */
+</verb></tscreen>
 
-  widget->style = gtk_style_attach (widget->style, widget->window);
+<!-- ----------------------------------------------------------------- -->
+<sect1> Scribble
+<p>
+<tscreen><verb>
+/* example-start scribble-simple scribble-simple.c */
 
-  gdk_window_set_user_data (widget->window, widget);
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
-  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+#include <gtk/gtk.h>
+
+/* Backing pixmap for drawing area */
+static GdkPixmap *pixmap = NULL;
+
+/* Create a new backing pixmap of the appropriate size */
+static gint
+configure_event (GtkWidget *widget, GdkEventConfigure *event)
+{
+  if (pixmap)
+    gdk_pixmap_unref(pixmap);
+
+  pixmap = gdk_pixmap_new(widget->window,
+                         widget->allocation.width,
+                         widget->allocation.height,
+                         -1);
+  gdk_draw_rectangle (pixmap,
+                     widget->style->white_gc,
+                     TRUE,
+                     0, 0,
+                     widget->allocation.width,
+                     widget->allocation.height);
+
+  return TRUE;
 }
 
-static void 
-gtk_dial_size_request (GtkWidget      *widget,
-                      GtkRequisition *requisition)
+/* Redraw the screen from the backing pixmap */
+static gint
+expose_event (GtkWidget *widget, GdkEventExpose *event)
 {
-  requisition->width = DIAL_DEFAULT_SIZE;
-  requisition->height = DIAL_DEFAULT_SIZE;
+  gdk_draw_pixmap(widget->window,
+                 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                 pixmap,
+                 event->area.x, event->area.y,
+                 event->area.x, event->area.y,
+                 event->area.width, event->area.height);
+
+  return FALSE;
 }
 
+/* Draw a rectangle on the screen */
 static void
-gtk_dial_size_allocate (GtkWidget     *widget,
-                       GtkAllocation *allocation)
+draw_brush (GtkWidget *widget, gdouble x, gdouble y)
 {
-  GtkDial *dial;
+  GdkRectangle update_rect;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_DIAL (widget));
-  g_return_if_fail (allocation != NULL);
+  update_rect.x = x - 5;
+  update_rect.y = y - 5;
+  update_rect.width = 10;
+  update_rect.height = 10;
+  gdk_draw_rectangle (pixmap,
+                     widget->style->black_gc,
+                     TRUE,
+                     update_rect.x, update_rect.y,
+                     update_rect.width, update_rect.height);
+  gtk_widget_draw (widget, &amp;update_rect);
+}
 
-  widget->allocation = *allocation;
-  dial = GTK_DIAL (widget);
+static gint
+button_press_event (GtkWidget *widget, GdkEventButton *event)
+{
+  if (event->button == 1 &amp;&amp; pixmap != NULL)
+    draw_brush (widget, event->x, event->y);
 
-  if (GTK_WIDGET_REALIZED (widget))
-    {
+  return TRUE;
+}
 
-      gdk_window_move_resize (widget->window,
-                             allocation->x, allocation->y,
-                             allocation->width, allocation->height);
+static gint
+motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
+{
+  int x, y;
+  GdkModifierType state;
 
+  if (event->is_hint)
+    gdk_window_get_pointer (event->window, &amp;x, &amp;y, &amp;state);
+  else
+    {
+      x = event->x;
+      y = event->y;
+      state = event->state;
     }
-  dial->radius = MIN(allocation->width,allocation->height) * 0.45;
-  dial->pointer_width = dial->radius / 5;
+    
+  if (state &amp; GDK_BUTTON1_MASK &amp;&amp; pixmap != NULL)
+    draw_brush (widget, x, y);
+  
+  return TRUE;
 }
 
-static gint
-gtk_dial_expose (GtkWidget      *widget,
-                GdkEventExpose *event)
+void
+quit ()
 {
-  GtkDial *dial;
-  GdkPoint points[3];
-  gdouble s,c;
-  gdouble theta;
-  gint xc, yc;
-  gint tick_length;
-  gint i;
+  gtk_exit (0);
+}
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *drawing_area;
+  GtkWidget *vbox;
 
-  if (event->count > 0)
-    return FALSE;
-  
-  dial = GTK_DIAL (widget);
+  GtkWidget *button;
 
-  gdk_window_clear_area (widget->window,
-                        0, 0,
-                        widget->allocation.width,
-                        widget->allocation.height);
+  gtk_init (&amp;argc, &amp;argv);
 
-  xc = widget->allocation.width/2;
-  yc = widget->allocation.height/2;
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (window, "Test Input");
 
-  /* Draw ticks */
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_widget_show (vbox);
 
-  for (i=0; i<25; i++)
-    {
-      theta = (i*M_PI/18. - M_PI/6.);
-      s = sin(theta);
-      c = cos(theta);
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (quit), NULL);
 
-      tick_length = (i%6 == 0) ? dial->pointer_width : dial->pointer_width/2;
-      
-      gdk_draw_line (widget->window,
-                    widget->style->fg_gc[widget->state],
-                    xc + c*(dial->radius - tick_length),
-                    yc - s*(dial->radius - tick_length),
-                    xc + c*dial->radius,
-                    yc - s*dial->radius);
-    }
+  /* Create the drawing area */
 
-  /* Draw pointer */
+  drawing_area = gtk_drawing_area_new ();
+  gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
+  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
 
-  s = sin(dial->angle);
-  c = cos(dial->angle);
+  gtk_widget_show (drawing_area);
 
+  /* Signals used to handle backing pixmap */
 
-  points[0].x = xc + s*dial->pointer_width/2;
-  points[0].y = yc + c*dial->pointer_width/2;
-  points[1].x = xc + c*dial->radius;
-  points[1].y = yc - s*dial->radius;
-  points[2].x = xc - s*dial->pointer_width/2;
-  points[2].y = yc - c*dial->pointer_width/2;
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
+                     (GtkSignalFunc) expose_event, NULL);
+  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
+                     (GtkSignalFunc) configure_event, NULL);
 
-  gtk_draw_polygon (widget->style,
-                   widget->window,
-                   GTK_STATE_NORMAL,
-                   GTK_SHADOW_OUT,
-                   points, 3,
-                   TRUE);
-  
-  return FALSE;
-}
+  /* Event signals */
 
-static gint
-gtk_dial_button_press (GtkWidget      *widget,
-                      GdkEventButton *event)
-{
-  GtkDial *dial;
-  gint dx, dy;
-  double s, c;
-  double d_parallel;
-  double d_perpendicular;
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
+                     (GtkSignalFunc) motion_notify_event, NULL);
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
+                     (GtkSignalFunc) button_press_event, NULL);
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
+                        | GDK_LEAVE_NOTIFY_MASK
+                        | GDK_BUTTON_PRESS_MASK
+                        | GDK_POINTER_MOTION_MASK
+                        | GDK_POINTER_MOTION_HINT_MASK);
 
-  dial = GTK_DIAL (widget);
+  /* .. And a quit button */
+  button = gtk_button_new_with_label ("Quit");
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
 
-  /* Determine if button press was within pointer region - we 
-     do this by computing the parallel and perpendicular distance of
-     the point where the mouse was pressed from the line passing through
-     the pointer */
-  
-  dx = event->x - widget->allocation.width / 2;
-  dy = widget->allocation.height / 2 - event->y;
-  
-  s = sin(dial->angle);
-  c = cos(dial->angle);
-  
-  d_parallel = s*dy + c*dx;
-  d_perpendicular = fabs(s*dx - c*dy);
-  
-  if (!dial->button &amp;&amp;
-      (d_perpendicular < dial->pointer_width/2) &amp;&amp;
-      (d_parallel > - dial->pointer_width))
-    {
-      gtk_grab_add (widget);
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            GTK_OBJECT (window));
+  gtk_widget_show (button);
 
-      dial->button = event->button;
+  gtk_widget_show (window);
 
-      gtk_dial_update_mouse (dial, event->x, event->y);
-    }
+  gtk_main ();
 
-  return FALSE;
+  return 0;
 }
+/* example-end */
+</verb></tscreen>
 
-static gint
-gtk_dial_button_release (GtkWidget      *widget,
-                         GdkEventButton *event)
+<!-- ***************************************************************** -->
+<sect> List Widget
+<!-- ***************************************************************** -->
+<p>
+NOTE: The GtkList widget has been superseded by the GtkCList
+widget. It is detailed here just for completeness.
+
+The GtkList widget is designed to act as a vertical container for
+widgets that should be of the type GtkListItem.
+
+A GtkList widget has its own window to receive events and its own
+background color which is usually white. As it is directly derived
+from a GtkContainer it can be treated as such by using the
+GTK_CONTAINER(List) macro, see the GtkContainer widget for more on
+this. One should already be familiar with the usage of a GList and
+its related functions g_list_*() to be able to use the GtkList widget
+to it full extent.
+
+There is one field inside the structure definition of the GtkList
+widget that will be of greater interest to us, this is:
+
+<tscreen><verb>
+struct _GtkList
 {
-  GtkDial *dial;
+  ...
+  GList *selection;
+  guint selection_mode;
+  ...
+}; 
+</verb></tscreen>
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+The selection field of a GtkList points to a linked list of all items
+that are currently selected, or NULL if the selection is empty.  So to
+learn about the current selection we read the GTK_LIST()->selection
+field, but do not modify it since the internal fields are maintained
+by the gtk_list_*() functions.
 
-  dial = GTK_DIAL (widget);
+The selection_mode of the GtkList determines the selection facilities
+of a GtkList and therefore the contents of the GTK_LIST()->selection
+field. The selection_mode may be one of the following:
 
-  if (dial->button == event->button)
-    {
-      gtk_grab_remove (widget);
+<itemize>
+<item> GTK_SELECTION_SINGLE - The selection is either NULL
+                        or contains a GList pointer
+                        for a single selected item.
 
-      dial->button = 0;
+<item> GTK_SELECTION_BROWSE -  The selection is NULL if the list
+                        contains no widgets or insensitive
+                        ones only, otherwise it contains
+                        a GList pointer for one GList
+                        structure, and therefore exactly
+                        one list item.
 
-      if (dial->policy == GTK_UPDATE_DELAYED)
-       gtk_timeout_remove (dial->timer);
-      
-      if ((dial->policy != GTK_UPDATE_CONTINUOUS) &amp;&amp;
-         (dial->old_value != dial->adjustment->value))
-       gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
-    }
+<item> GTK_SELECTION_MULTIPLE -  The selection is NULL if no list
+                        items are selected or a GList pointer
+                        for the first selected item. That
+                        in turn points to a GList structure
+                        for the second selected item and so
+                        on.
 
-  return FALSE;
-}
+<item> GTK_SELECTION_EXTENDED - The selection is always NULL.
+</itemize>
 
-static gint
-gtk_dial_motion_notify (GtkWidget      *widget,
-                        GdkEventMotion *event)
-{
-  GtkDial *dial;
-  GdkModifierType mods;
-  gint x, y, mask;
+The default is GTK_SELECTION_MULTIPLE.
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+<!-- ----------------------------------------------------------------- -->
+<sect1> Signals
+<p>
+<tscreen><verb>
+void selection_changed( GtkList *list );
+</verb></tscreen>
 
-  dial = GTK_DIAL (widget);
+This signal will be invoked whenever the selection field of a GtkList
+has changed. This happens when a child of the GtkList got selected or
+deselected.
 
-  if (dial->button != 0)
-    {
-      x = event->x;
-      y = event->y;
+<tscreen><verb>
+void select_child( GtkList   *list,
+                   GtkWidget *child);
+</verb></tscreen>
 
-      if (event->is_hint || (event->window != widget->window))
-       gdk_window_get_pointer (widget->window, &amp;x, &amp;y, &amp;mods);
+This signal is invoked when a child of the GtkList is about to get
+selected. This happens mainly on calls to gtk_list_select_item(),
+gtk_list_select_child(), button presses and sometimes indirectly
+triggered on some else occasions where children get added to or
+removed from the GtkList.
 
-      switch (dial->button)
-       {
-       case 1:
-         mask = GDK_BUTTON1_MASK;
-         break;
-       case 2:
-         mask = GDK_BUTTON2_MASK;
-         break;
-       case 3:
-         mask = GDK_BUTTON3_MASK;
-         break;
-       default:
-         mask = 0;
-         break;
-       }
+<tscreen><verb>
+void unselect_child( GtkList   *list,
+                     GtkWidget *child );
+</verb></tscreen>
 
-      if (mods &amp; mask)
-       gtk_dial_update_mouse (dial, x,y);
-    }
+This signal is invoked when a child of the GtkList is about to get
+deselected. This happens mainly on calls to gtk_list_unselect_item(),
+gtk_list_unselect_child(), button presses and sometimes indirectly
+triggered on some else occasions where children get added to or
+removed from the GtkList.
 
-  return FALSE;
-}
+<!-- ----------------------------------------------------------------- -->
+<sect1> Functions
+<p>
+<tscreen><verb>
+guint gtk_list_get_type( void );
+</verb></tscreen>
 
-static gint
-gtk_dial_timer (GtkDial *dial)
-{
-  g_return_val_if_fail (dial != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
+Returns the `GtkList' type identifier.
 
-  if (dial->policy == GTK_UPDATE_DELAYED)
-    gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+<tscreen><verb>
+GtkWidget *gtk_list_new( void );
+</verb></tscreen>
 
-  return FALSE;
-}
+Create a new GtkList object. The new widget is returned as a pointer
+to a GtkWidget object. NULL is returned on failure.
 
-static void
-gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
-{
-  gint xc, yc;
-  gfloat old_value;
+<tscreen><verb>
+void gtk_list_insert_items( GtkList *list,
+                            GList   *items,
+                            gint     position );
+</verb></tscreen>
 
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+Insert list items into the list, starting at <tt/position/.
+<tt/items/ is a doubly linked list where each nodes data pointer is
+expected to point to a newly created GtkListItem.  The GList nodes of
+<tt/items/ are taken over by the list.
 
-  xc = GTK_WIDGET(dial)->allocation.width / 2;
-  yc = GTK_WIDGET(dial)->allocation.height / 2;
+<tscreen><verb>
+void gtk_list_append_items( GtkList *list,
+                            GList   *items);
+</verb></tscreen>
 
-  old_value = dial->adjustment->value;
-  dial->angle = atan2(yc-y, x-xc);
+Insert list items just like gtk_list_insert_items() at the end of the
+list. The GList nodes of <tt/items/ are taken over by the list.
 
-  if (dial->angle < -M_PI/2.)
-    dial->angle += 2*M_PI;
+<tscreen><verb>
+void gtk_list_prepend_items( GtkList *list,
+                             GList   *items);
+</verb></tscreen>
 
-  if (dial->angle < -M_PI/6)
-    dial->angle = -M_PI/6;
+Insert list items just like gtk_list_insert_items() at the very
+beginning of the list. The GList nodes of <tt/items/ are taken over by
+the list.
 
-  if (dial->angle > 7.*M_PI/6.)
-    dial->angle = 7.*M_PI/6.;
+<tscreen><verb>
+void gtk_list_remove_items( GtkList *list,
+                            GList   *items);
+</verb></tscreen>
 
-  dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
-    (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
+Remove list items from the list. <tt/items/ is a doubly linked list
+where each nodes data pointer is expected to point to a direct child
+of list. It is the callers responsibility to make a call to
+g_list_free(items) afterwards. Also the caller has to destroy the list
+items himself.
 
-  if (dial->adjustment->value != old_value)
-    {
-      if (dial->policy == GTK_UPDATE_CONTINUOUS)
-       {
-         gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
-       }
-      else
-       {
-         gtk_widget_draw (GTK_WIDGET(dial), NULL);
+<tscreen><verb>
+void gtk_list_clear_items( GtkList *list,
+                           gint start,
+                           gint end );
+</verb></tscreen>
 
-         if (dial->policy == GTK_UPDATE_DELAYED)
-           {
-             if (dial->timer)
-               gtk_timeout_remove (dial->timer);
+Remove and destroy list items from the list. A widget is affected if
+its current position within the list is in the range specified by
+<tt/start/ and <tt/end/.
 
-             dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
-                                            (GtkFunction) gtk_dial_timer,
-                                            (gpointer) dial);
-           }
-       }
-    }
-}
+<tscreen><verb>
+void gtk_list_select_item( GtkList *list,
+                           gint     item );
+</verb></tscreen>
 
-static void
-gtk_dial_update (GtkDial *dial)
-{
-  gfloat new_value;
-  
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+Invoke the select_child signal for a list item specified through its
+current position within the list.
 
-  new_value = dial->adjustment->value;
-  
-  if (new_value < dial->adjustment->lower)
-    new_value = dial->adjustment->lower;
+<tscreen><verb>
+void gtk_list_unselect_item( GtkList *list,
+                             gint     item);
+</verb></tscreen>
 
-  if (new_value > dial->adjustment->upper)
-    new_value = dial->adjustment->upper;
+Invoke the unselect_child signal for a list item specified through its
+current position within the list.
 
-  if (new_value != dial->adjustment->value)
-    {
-      dial->adjustment->value = new_value;
-      gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
-    }
+<tscreen><verb>
+void gtk_list_select_child( GtkList *list,
+                            GtkWidget *child);
+</verb></tscreen>
 
-  dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
-    (dial->adjustment->upper - dial->adjustment->lower);
+Invoke the select_child signal for the specified child.
 
-  gtk_widget_draw (GTK_WIDGET(dial), NULL);
-}
+<tscreen><verb>
+void gtk_list_unselect_child( GtkList   *list,
+                              GtkWidget *child);
+</verb></tscreen>
 
-static void
-gtk_dial_adjustment_changed (GtkAdjustment *adjustment,
-                             gpointer       data)
-{
-  GtkDial *dial;
+Invoke the unselect_child signal for the specified child.
 
-  g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
+<tscreen><verb>
+gint gtk_list_child_position( GtkList *list,
+                              GtkWidget *child);
+</verb></tscreen>
 
-  dial = GTK_DIAL (data);
+Return the position of <tt/child/ within the list. "-1" is returned on
+failure.
 
-  if ((dial->old_value != adjustment->value) ||
-      (dial->old_lower != adjustment->lower) ||
-      (dial->old_upper != adjustment->upper))
-    {
-      gtk_dial_update (dial);
+<tscreen><verb>
+void gtk_list_set_selection_mode( GtkList         *list,
+                                  GtkSelectionMode mode );
+</verb></tscreen>
 
-      dial->old_value = adjustment->value;
-      dial->old_lower = adjustment->lower;
-      dial->old_upper = adjustment->upper;
-    }
-}
+Set the selection mode MODE which can be of GTK_SELECTION_SINGLE,
+GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or
+GTK_SELECTION_EXTENDED.
 
-static void
-gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
-                                   gpointer       data)
-{
-  GtkDial *dial;
+<tscreen><verb>
+GtkList *GTK_LIST( gpointer obj );
+</verb></tscreen>
 
-  g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
+Cast a generic pointer to `GtkList *'. *Note Standard Macros::, for
+more info.
 
-  dial = GTK_DIAL (data);
+<tscreen><verb>
+GtkListClass *GTK_LIST_CLASS( gpointer class);
+</verb></tscreen>
 
-  if (dial->old_value != adjustment->value)
-    {
-      gtk_dial_update (dial);
+Cast a generic pointer to `GtkListClass*'. *Note Standard Macros::,
+for more info.
 
-      dial->old_value = adjustment->value;
-    }
-}
-/* example-end */
+<tscreen><verb>
+gint GTK_IS_LIST( gpointer obj);
 </verb></tscreen>
 
+Determine if a generic pointer refers to a `GtkList' object. *Note
+Standard Macros::, for more info.
+
 <!-- ----------------------------------------------------------------- -->
-<sect1> Scribble
+<sect1> Example
 <p>
+Following is an example program that will print out the changes of the
+selection of a GtkList, and lets you "arrest" list items into a prison
+by selecting them with the rightmost mouse button.
+
 <tscreen><verb>
-/* example-start scribble-simple scribble-simple.c */
+/* example-start list list.c */
 
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+/* Include the gtk+ header files
+ * Include stdio.h, we need that for the printf() function
  */
+#include        <gtk/gtk.h>
+#include        <stdio.h>
 
-#include <gtk/gtk.h>
-
-/* Backing pixmap for drawing area */
-static GdkPixmap *pixmap = NULL;
+/* This is our data identification string to store
+ * data in list items
+ */
+const gchar *list_item_data_key="list_item_data";
 
-/* Create a new backing pixmap of the appropriate size */
-static gint
-configure_event (GtkWidget *widget, GdkEventConfigure *event)
-{
-  if (pixmap)
-    gdk_pixmap_unref(pixmap);
 
-  pixmap = gdk_pixmap_new(widget->window,
-                         widget->allocation.width,
-                         widget->allocation.height,
-                         -1);
-  gdk_draw_rectangle (pixmap,
-                     widget->style->white_gc,
-                     TRUE,
-                     0, 0,
-                     widget->allocation.width,
-                     widget->allocation.height);
+/* prototypes for signal handler that we are going to connect
+ * to the GtkList widget
+ */
+static void  sigh_print_selection( GtkWidget *gtklist,
+                                   gpointer   func_data);
 
-  return TRUE;
-}
+static void  sigh_button_event( GtkWidget      *gtklist,
+                                GdkEventButton *event,
+                                GtkWidget      *frame );
 
-/* Redraw the screen from the backing pixmap */
-static gint
-expose_event (GtkWidget *widget, GdkEventExpose *event)
-{
-  gdk_draw_pixmap(widget->window,
-                 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-                 pixmap,
-                 event->area.x, event->area.y,
-                 event->area.x, event->area.y,
-                 event->area.width, event->area.height);
 
-  return FALSE;
-}
+/* Main function to set up the user interface */
 
-/* Draw a rectangle on the screen */
-static void
-draw_brush (GtkWidget *widget, gdouble x, gdouble y)
-{
-  GdkRectangle update_rect;
+gint main (int    argc,
+           gchar *argv[])
+{                                  
+    GtkWidget *separator;
+    GtkWidget *window;
+    GtkWidget *vbox;
+    GtkWidget *scrolled_window;
+    GtkWidget *frame;
+    GtkWidget *gtklist;
+    GtkWidget *button;
+    GtkWidget *list_item;
+    GList *dlist;
+    guint i;
+    gchar buffer[64];
+    
+    
+    /* Initialize gtk+ (and subsequently gdk) */
 
-  update_rect.x = x - 5;
-  update_rect.y = y - 5;
-  update_rect.width = 10;
-  update_rect.height = 10;
-  gdk_draw_rectangle (pixmap,
-                     widget->style->black_gc,
-                     TRUE,
-                     update_rect.x, update_rect.y,
-                     update_rect.width, update_rect.height);
-  gtk_widget_draw (widget, &amp;update_rect);
+    gtk_init(&amp;argc, &amp;argv);
+    
+    
+    /* Create a window to put all the widgets in
+     * connect gtk_main_quit() to the "destroy" event of
+     * the window to handle window manager close-window-events
+     */
+    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
+    gtk_signal_connect(GTK_OBJECT(window),
+                      "destroy",
+                      GTK_SIGNAL_FUNC(gtk_main_quit),
+                      NULL);
+    
+    
+    /* Inside the window we need a box to arrange the widgets
+     * vertically */
+    vbox=gtk_vbox_new(FALSE, 5);
+    gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+    gtk_container_add(GTK_CONTAINER(window), vbox);
+    gtk_widget_show(vbox);
+    
+    /* This is the scrolled window to put the GtkList widget inside */
+    scrolled_window=gtk_scrolled_window_new(NULL, NULL);
+    gtk_widget_set_usize(scrolled_window, 250, 150);
+    gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
+    gtk_widget_show(scrolled_window);
+    
+    /* Create the GtkList widget.
+     * Connect the sigh_print_selection() signal handler
+     * function to the "selection_changed" signal of the GtkList
+     * to print out the selected items each time the selection
+     * has changed */
+    gtklist=gtk_list_new();
+    gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
+                                           gtklist);
+    gtk_widget_show(gtklist);
+    gtk_signal_connect(GTK_OBJECT(gtklist),
+                      "selection_changed",
+                      GTK_SIGNAL_FUNC(sigh_print_selection),
+                      NULL);
+    
+    /* We create a "Prison" to put a list item in ;) */
+    frame=gtk_frame_new("Prison");
+    gtk_widget_set_usize(frame, 200, 50);
+    gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
+    gtk_container_add(GTK_CONTAINER(vbox), frame);
+    gtk_widget_show(frame);
+    
+    /* Connect the sigh_button_event() signal handler to the GtkList
+     * which will handle the "arresting" of list items
+     */
+    gtk_signal_connect(GTK_OBJECT(gtklist),
+                      "button_release_event",
+                      GTK_SIGNAL_FUNC(sigh_button_event),
+                      frame);
+    
+    /* Create a separator */
+    separator=gtk_hseparator_new();
+    gtk_container_add(GTK_CONTAINER(vbox), separator);
+    gtk_widget_show(separator);
+    
+    /* Finally create a button and connect it's "clicked" signal
+     * to the destruction of the window */
+    button=gtk_button_new_with_label("Close");
+    gtk_container_add(GTK_CONTAINER(vbox), button);
+    gtk_widget_show(button);
+    gtk_signal_connect_object(GTK_OBJECT(button),
+                             "clicked",
+                             GTK_SIGNAL_FUNC(gtk_widget_destroy),
+                             GTK_OBJECT(window));
+    
+    
+    /* Now we create 5 list items, each having it's own
+     * label and add them to the GtkList using gtk_container_add()
+     * Also we query the text string from the label and
+     * associate it with the list_item_data_key for each list item
+     */
+    for (i=0; i<5; i++) {
+       GtkWidget       *label;
+       gchar           *string;
+       
+       sprintf(buffer, "ListItemContainer with Label #%d", i);
+       label=gtk_label_new(buffer);
+       list_item=gtk_list_item_new();
+       gtk_container_add(GTK_CONTAINER(list_item), label);
+       gtk_widget_show(label);
+       gtk_container_add(GTK_CONTAINER(gtklist), list_item);
+       gtk_widget_show(list_item);
+       gtk_label_get(GTK_LABEL(label), &amp;string);
+       gtk_object_set_data(GTK_OBJECT(list_item),
+                           list_item_data_key,
+                           string);
+    }
+    /* Here, we are creating another 5 labels, this time
+     * we use gtk_list_item_new_with_label() for the creation
+     * we can't query the text string from the label because
+     * we don't have the labels pointer and therefore
+     * we just associate the list_item_data_key of each
+     * list item with the same text string.
+     * For adding of the list items we put them all into a doubly
+     * linked list (GList), and then add them by a single call to
+     * gtk_list_append_items().
+     * Because we use g_list_prepend() to put the items into the
+     * doubly linked list, their order will be descending (instead
+     * of ascending when using g_list_append())
+     */
+    dlist=NULL;
+    for (; i<10; i++) {
+       sprintf(buffer, "List Item with Label %d", i);
+       list_item=gtk_list_item_new_with_label(buffer);
+       dlist=g_list_prepend(dlist, list_item);
+       gtk_widget_show(list_item);
+       gtk_object_set_data(GTK_OBJECT(list_item),
+                           list_item_data_key,
+                           "ListItem with integrated Label");
+    }
+    gtk_list_append_items(GTK_LIST(gtklist), dlist);
+    
+    /* Finally we want to see the window, don't we? ;) */
+    gtk_widget_show(window);
+    
+    /* Fire up the main event loop of gtk */
+    gtk_main();
+    
+    /* We get here after gtk_main_quit() has been called which
+     * happens if the main window gets destroyed
+     */
+    return(0);
 }
 
-static gint
-button_press_event (GtkWidget *widget, GdkEventButton *event)
+/* This is the signal handler that got connected to button
+ * press/release events of the GtkList
+ */
+void sigh_button_event( GtkWidget      *gtklist,
+                        GdkEventButton *event,
+                        GtkWidget      *frame )
 {
-  if (event->button == 1 &amp;&amp; pixmap != NULL)
-    draw_brush (widget, event->x, event->y);
-
-  return TRUE;
+    /* We only do something if the third (rightmost mouse button
+     * was released
+     */
+    if (event->type==GDK_BUTTON_RELEASE &amp;&amp;
+       event->button==3) {
+       GList           *dlist, *free_list;
+       GtkWidget       *new_prisoner;
+       
+       /* Fetch the currently selected list item which
+        * will be our next prisoner ;)
+        */
+       dlist=GTK_LIST(gtklist)->selection;
+       if (dlist)
+               new_prisoner=GTK_WIDGET(dlist->data);
+       else
+               new_prisoner=NULL;
+       
+       /* Look for already imprisoned list items, we
+        * will put them back into the list.
+        * Remember to free the doubly linked list that
+        * gtk_container_children() returns
+        */
+       dlist=gtk_container_children(GTK_CONTAINER(frame));
+       free_list=dlist;
+       while (dlist) {
+           GtkWidget       *list_item;
+           
+           list_item=dlist->data;
+           
+           gtk_widget_reparent(list_item, gtklist);
+           
+           dlist=dlist->next;
+       }
+       g_list_free(free_list);
+       
+       /* If we have a new prisoner, remove him from the
+        * GtkList and put him into the frame "Prison".
+        * We need to unselect the item first.
+        */
+       if (new_prisoner) {
+           GList   static_dlist;
+           
+           static_dlist.data=new_prisoner;
+           static_dlist.next=NULL;
+           static_dlist.prev=NULL;
+           
+           gtk_list_unselect_child(GTK_LIST(gtklist),
+                                   new_prisoner);
+           gtk_widget_reparent(new_prisoner, frame);
+       }
+    }
 }
 
-static gint
-motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
+/* This is the signal handler that gets called if GtkList
+ * emits the "selection_changed" signal
+ */
+void sigh_print_selection( GtkWidget *gtklist,
+                           gpointer   func_data)
 {
-  int x, y;
-  GdkModifierType state;
-
-  if (event->is_hint)
-    gdk_window_get_pointer (event->window, &amp;x, &amp;y, &amp;state);
-  else
-    {
-      x = event->x;
-      y = event->y;
-      state = event->state;
+    GList   *dlist;
+    
+    /* Fetch the doubly linked list of selected items
+     * of the GtkList, remember to treat this as read-only!
+     */
+    dlist=GTK_LIST(gtklist)->selection;
+    
+    /* If there are no selected items there is nothing more
+     * to do than just telling the user so
+     */
+    if (!dlist) {
+       g_print("Selection cleared\n");
+       return;
     }
+    /* Ok, we got a selection and so we print it
+     */
+    g_print("The selection is a ");
     
-  if (state &amp; GDK_BUTTON1_MASK &amp;&amp; pixmap != NULL)
-    draw_brush (widget, x, y);
-  
-  return TRUE;
+    /* Get the list item from the doubly linked list
+     * and then query the data associated with list_item_data_key.
+     * We then just print it */
+    while (dlist) {
+       GtkObject       *list_item;
+       gchar           *item_data_string;
+       
+       list_item=GTK_OBJECT(dlist->data);
+       item_data_string=gtk_object_get_data(list_item,
+                                            list_item_data_key);
+       g_print("%s ", item_data_string);
+       
+       dlist=dlist->next;
+    }
+    g_print("\n");
 }
+/* example-end */
+</verb></tscreen>
 
-void
-quit ()
-{
-  gtk_exit (0);
-}
+<!-- ----------------------------------------------------------------- -->
+<sect1> List Item Widget
+<p>
+The GtkListItem widget is designed to act as a container holding up to
+one child, providing functions for selection/deselection just like the
+GtkList widget requires them for its children.
 
-int
-main (int argc, char *argv[])
-{
-  GtkWidget *window;
-  GtkWidget *drawing_area;
-  GtkWidget *vbox;
+A GtkListItem has its own window to receive events and has its own
+background color which is usually white.
 
-  GtkWidget *button;
+As it is directly derived from a GtkItem it can be treated as such by
+using the GTK_ITEM(ListItem) macro, see the GtkItem widget for more on
+this. Usually a GtkListItem just holds a label to identify e.g. a
+filename within a GtkList -- therefore the convenience function
+gtk_list_item_new_with_label() is provided. The same effect can be
+achieved by creating a GtkLabel on its own, setting its alignment to
+xalign=0 and yalign=0.5 with a subsequent container addition to the
+GtkListItem.
 
-  gtk_init (&amp;argc, &amp;argv);
+As one is not forced to add a GtkLabel to a GtkListItem, you could
+also add a GtkVBox or a GtkArrow etc. to the GtkListItem.
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_widget_set_name (window, "Test Input");
+<!-- ----------------------------------------------------------------- -->
+<sect1> Signals
+<p>
+A GtkListItem does not create new signals on its own, but inherits
+the signals of a GtkItem. *Note GtkItem::, for more info.
 
-  vbox = gtk_vbox_new (FALSE, 0);
-  gtk_container_add (GTK_CONTAINER (window), vbox);
-  gtk_widget_show (vbox);
+<!-- ----------------------------------------------------------------- -->
+<sect1> Functions
+<p>
+<tscreen><verb>
+guint gtk_list_item_get_type( void );
+</verb></tscreen>
 
-  gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                     GTK_SIGNAL_FUNC (quit), NULL);
+Returns the `GtkListItem' type identifier.
 
-  /* Create the drawing area */
+<tscreen><verb>
+GtkWidget *gtk_list_item_new( void );
+</verb></tscreen>
 
-  drawing_area = gtk_drawing_area_new ();
-  gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
-  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
+Create a new GtkListItem object. The new widget is returned as a
+pointer to a GtkWidget object. NULL is returned on failure.
 
-  gtk_widget_show (drawing_area);
+<tscreen><verb>
+GtkWidget *gtk_list_item_new_with_label( gchar *label );
+</verb></tscreen>
 
-  /* Signals used to handle backing pixmap */
+Create a new GtkListItem object, having a single GtkLabel as the sole
+child. The new widget is returned as a pointer to a GtkWidget
+object. NULL is returned on failure.
 
-  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
-                     (GtkSignalFunc) expose_event, NULL);
-  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
-                     (GtkSignalFunc) configure_event, NULL);
+<tscreen><verb>
+void gtk_list_item_select( GtkListItem *list_item );
+</verb></tscreen>
 
-  /* Event signals */
+This function is basically a wrapper around a call to gtk_item_select
+(GTK_ITEM (list_item)) which will emit the select signal.  *Note
+GtkItem::, for more info.
 
-  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
-                     (GtkSignalFunc) motion_notify_event, NULL);
-  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
-                     (GtkSignalFunc) button_press_event, NULL);
+<tscreen><verb>
+void gtk_list_item_deselect( GtkListItem *list_item );
+</verb></tscreen>
 
-  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
-                        | GDK_LEAVE_NOTIFY_MASK
-                        | GDK_BUTTON_PRESS_MASK
-                        | GDK_POINTER_MOTION_MASK
-                        | GDK_POINTER_MOTION_HINT_MASK);
+This function is basically a wrapper around a call to
+gtk_item_deselect (GTK_ITEM (list_item)) which will emit the deselect
+signal.  *Note GtkItem::, for more info.
 
-  /* .. And a quit button */
-  button = gtk_button_new_with_label ("Quit");
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+<tscreen><verb>
+GtkListItem *GTK_LIST_ITEM( gpointer obj );
+</verb></tscreen>
 
-  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
-                            GTK_OBJECT (window));
-  gtk_widget_show (button);
+Cast a generic pointer to `GtkListItem*'. *Note Standard Macros::, for
+more info.
 
-  gtk_widget_show (window);
+<tscreen><verb>
+GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class );
+</verb></tscreen>
 
-  gtk_main ();
+Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::,
+for more info.
 
-  return 0;
-}
-/* example-end */
+<tscreen><verb>
+gint GTK_IS_LIST_ITEM( gpointer obj );
 </verb></tscreen>
 
+Determine if a generic pointer refers to a `GtkListItem' object.
+*Note Standard Macros::, for more info.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Example
+<p>
+Please see the GtkList example on this, which covers the usage of a
+GtkListItem as well.
+
+
 </article>
index c85e11796dc883e98d69a81dd10db10c046d7db6..30c962a6c478818f401adb6c976bde02ea2eb91b 100644 (file)
@@ -11,7 +11,7 @@ Tony Gale <tt><htmlurl url="mailto:gale@gtk.org"
                              name="&lt;gale@gtk.org&gt;"></tt>
 Ian Main <tt><htmlurl url="mailto:imain@gtk.org"
                              name="&lt;imain@gtk.org&gt;"></tt>,
-<date>January 27th, 1999
+<date>January 28th, 1999
 
 <!-- ***************************************************************** -->
 <sect>Introduction
@@ -4782,471 +4782,409 @@ int main (int argc, char *argv[])
 <sect> Container Widgets
 <!-- ***************************************************************** -->
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> Notebooks
-<p>
-The NoteBook Widget is a collection of 'pages' that overlap each
-other, each page contains different information. This widget has
-become more common lately in GUI programming, and it is a good way to
-show blocks of similar information that warrant separation in their
-display.
+<!-- ----------------------------------------------------------------- -->   
+<sect1>The EventBox <label id="sec_EventBox">
+<p> 
+Some GTK widgets don't have associated X windows, so they just draw on
+their parents. Because of this, they cannot receive events and if they
+are incorrectly sized, they don't clip so you can get messy
+overwriting etc. If you require more from these widgets, the EventBox
+is for you.
 
-The first function call you will need to know, as you can probably
-guess by now, is used to create a new notebook widget.
+At first glance, the EventBox widget might appear to be totally
+useless. It draws nothing on the screen and responds to no
+events. However, it does serve a function - it provides an X window
+for its child widget. This is important as many GTK widgets do not
+have an associated X window. Not having an X window saves memory and
+improves performance, but also has some drawbacks. A widget without an
+X window cannot receive events, and does not perform any clipping on
+its contents. Although the name <em/EventBox/ emphasizes the
+event-handling function, the widget can also be used for clipping.
+(and more, see the example below).
+
+To create a new EventBox widget, use:
 
 <tscreen><verb>
-GtkWidget *gtk_notebook_new( void );
+GtkWidget *gtk_event_box_new( void );
 </verb></tscreen>
 
-Once the notebook has been created, there are a number of functions
-that operate on the notebook widget. Let's look at them individually.
-
-The first one we will look at is how to position the page indicators.
-These page indicators or 'tabs' as they are referred to, can be
-positioned in four ways: top, bottom, left, or right.
+A child widget can then be added to this EventBox:
 
 <tscreen><verb>
-void gtk_notebook_set_tab_pos( GtkNotebook     *notebook,
-                               GtkPositionType  pos );
+gtk_container_add( GTK_CONTAINER(event_box), widget );
 </verb></tscreen>
 
-GtkPostionType will be one of the following, and they are pretty self explanatory:
-<itemize>
-<item> GTK_POS_LEFT
-<item> GTK_POS_RIGHT
-<item> GTK_POS_TOP
-<item> GTK_POS_BOTTOM
-</itemize>
-
-GTK_POS_TOP is the default.
-
-Next we will look at how to add pages to the notebook. There are three
-ways to add pages to the NoteBook. Let's look at the first two
-together as they are quite similar.
+The following example demonstrates both uses of an EventBox - a label
+is created that is clipped to a small box, and set up so that a
+mouse-click on the label causes the program to exit. Resizing the
+window reveals varying amounts of the label.
 
 <tscreen><verb>
-void gtk_notebook_append_page( GtkNotebook *notebook,
-                               GtkWidget   *child,
-                               GtkWidget   *tab_label );
+/* example-start eventbox eventbox.c */
 
-void gtk_notebook_prepend_page( GtkNotebook *notebook,
-                                GtkWidget   *child,
-                                GtkWidget   *tab_label );
+#include <gtk/gtk.h>
+
+int 
+main (int argc, char *argv[])
+{
+    GtkWidget *window;
+    GtkWidget *event_box;
+    GtkWidget *label;
+    
+    gtk_init (&amp;argc, &amp;argv);
+    
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    
+    gtk_window_set_title (GTK_WINDOW (window), "Event Box");
+    
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
+    
+    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+    
+    /* Create an EventBox and add it to our toplevel window */
+    
+    event_box = gtk_event_box_new ();
+    gtk_container_add (GTK_CONTAINER(window), event_box);
+    gtk_widget_show (event_box);
+    
+    /* Create a long label */
+    
+    label = gtk_label_new ("Click here to quit, quit, quit, quit, quit");
+    gtk_container_add (GTK_CONTAINER (event_box), label);
+    gtk_widget_show (label);
+    
+    /* Clip it short. */
+    gtk_widget_set_usize (label, 110, 20);
+    
+    /* And bind an action to it */
+    gtk_widget_set_events (event_box, GDK_BUTTON_PRESS_MASK);
+    gtk_signal_connect (GTK_OBJECT(event_box), "button_press_event",
+                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
+    
+    /* Yet one more thing you need an X window for ... */
+    
+    gtk_widget_realize (event_box);
+    gdk_window_set_cursor (event_box->window, gdk_cursor_new (GDK_HAND1));
+    
+    gtk_widget_show (window);
+    
+    gtk_main ();
+    
+    return(0);
+}
+/* example-end */
 </verb></tscreen>
 
-These functions add pages to the notebook by inserting them from the
-back of the notebook (append), or the front of the notebook (prepend).
-<tt/child/ is the widget that is placed within the notebook page, and
-<tt/tab_label/ is the label for the page being added. The <tt/child/
-widget must be created separately, and is typically a set of options
-setout witin one of the other container widgets, such as a table.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Fixed Container
+<p>
+The Fixed container allows you to place widgets at a fixed position
+within it's window, relative to it's upper left hand corner. The
+position of the widgets can be changed dynamically.
 
-The final function for adding a page to the notebook contains all of
-the properties of the previous two, but it allows you to specify what
-position you want the page to be in the notebook.
+There are only three functions associated with the fixed widget:
 
 <tscreen><verb>
-void gtk_notebook_insert_page( GtkNotebook *notebook,
-                               GtkWidget   *child,
-                               GtkWidget   *tab_label,
-                               gint         position );
+GtkWidget* gtk_fixed_new( void );
+
+void gtk_fixed_put( GtkFixed  *fixed,
+                    GtkWidget *widget,
+                    gint16     x,
+                    gint16     y );
+
+void gtk_fixed_move( GtkFixed  *fixed,
+                     GtkWidget *widget,
+                     gint16     x,
+                     gint16     y );
 </verb></tscreen>
 
-The parameters are the same as _append_ and _prepend_ except it
-contains an extra parameter, <tt/position/.  This parameter is used to
-specify what place this page will be inserted into.
+The function <tt/gtk_fixed_new/ allows you to create a new Fixed
+container.
 
-Now that we know how to add a page, lets see how we can remove a page
-from the notebook.
+<tt/gtk_fixed_put/ places <tt/widget/ in the container <tt/fixed/ at
+the position specified by <tt/x/ and <tt/y/.
+
+<tt/gtk_fixed_move/ allows the specified widget to be moved to a new
+position.
+
+The following example illustrates how to use the Fixed Container.
 
 <tscreen><verb>
-void gtk_notebook_remove_page( GtkNotebook *notebook,
-                               gint         page_num );
-</verb></tscreen>
+/* example-start fixed fixed.c */
 
-This function takes the page specified by <tt/page_num/ and removes it
-from the widget pointed to by <tt/notebook/.
+#include <gtk/gtk.h>
 
-To find out what the current page is in a notebook use the function:
+/* I'm going to be lazy and use some global variables to
+ * store the position of the widget within the fixed
+ * container */
+gint x=50;
+gint y=50;
 
-<tscreen><verb>
-gint gtk_notebook_get_current_page( GtkNotebook *notebook );
-</verb></tscreen>
+/* This callback function moves the button to a new position
+ * in the Fixed container. */
+void move_button( GtkWidget *widget,
+                  GtkWidget *fixed )
+{
+  x = (x+30)%300;
+  y = (y+50)%300;
+  gtk_fixed_move( GTK_FIXED(fixed), widget, x, y); 
+}
 
-These next two functions are simple calls to move the notebook page
-forward or backward. Simply provide the respective function call with
-the notebook widget you wish to operate on. Note: when the NoteBook is
-currently on the last page, and gtk_notebook_next_page is called, the
-notebook will wrap back to the first page. Likewise, if the NoteBook
-is on the first page, and gtk_notebook_prev_page is called, the
-notebook will wrap to the last page.
+int main( int   argc,
+          char *argv[] )
+{
+  /* GtkWidget is the storage type for widgets */
+  GtkWidget *window;
+  GtkWidget *fixed;
+  GtkWidget *button;
+  gint i;
 
-<tscreen><verb>
-void gtk_notebook_next_page( GtkNoteBook *notebook );
+  /* Initialise GTK */
+  gtk_init(&amp;argc, &amp;argv);
+    
+  /* Create a new window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(window), "Fixed Container");
 
-void gtk_notebook_prev_page( GtkNoteBook *notebook );
+  /* Here we connect the "destroy" event to a signal handler */ 
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+  /* Sets the border width of the window. */
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+  /* Create a Fixed Container */
+  fixed = gtk_fixed_new();
+  gtk_container_add(GTK_CONTAINER(window), fixed);
+  gtk_widget_show(fixed);
+  
+  for (i = 1 ; i <= 3 ; i++) {
+    /* Creates a new button with the label "Press me" */
+    button = gtk_button_new_with_label ("Press me");
+  
+    /* When the button receives the "clicked" signal, it will call the
+     * function move_button() passing it the Fixed Containter as its
+     * argument. */
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                       GTK_SIGNAL_FUNC (move_button), fixed);
+  
+    /* This packs the button into the fixed containers window. */
+    gtk_fixed_put (GTK_FIXED (fixed), button, i*50, i*50);
+  
+    /* The final step is to display this newly created widget. */
+    gtk_widget_show (button);
+  }
+
+  /* Display the window */
+  gtk_widget_show (window);
+    
+  /* Enter the event loop */
+  gtk_main ();
+    
+  return(0);
+}
+/* example-end */
 </verb></tscreen>
 
-This next function sets the 'active' page. If you wish the notebook to
-be opened to page 5 for example, you would use this function.  Without
-using this function, the notebook defaults to the first page.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Frames
+<p>
+Frames can be used to enclose one or a group of widgets with a box
+which can optionally be labelled. The position of the label and the
+style of the box can be altered to suit.
+
+A Frame can be created with the following function:
 
 <tscreen><verb>
-void gtk_notebook_set_page( GtkNotebook *notebook,
-                            gint         page_num );
+GtkWidget *gtk_frame_new( const gchar *label );
 </verb></tscreen>
 
-The next two functions add or remove the notebook page tabs and the
-notebook border respectively.
+The label is by default placed in the upper left hand corner of the
+frame. A value of NULL for the <tt/label/ argument will result in no
+label being displayed. The text of the label can be changed using the
+next function.
 
 <tscreen><verb>
-void gtk_notebook_set_show_tabs( GtkNotebook *notebook,
-                                 gboolean     show_tabs);
+void gtk_frame_set_label( GtkFrame    *frame,
+                          const gchar *label );
+</verb></tscreen>
 
-void gtk_notebook_set_show_border( GtkNotebook *notebook,
-                                   gboolean     show_border );
+The position of the label can be changed using this function:
+
+<tscreen><verb>
+void gtk_frame_set_label_align( GtkFrame *frame,
+                                gfloat    xalign,
+                                gfloat    yalign );
 </verb></tscreen>
 
-The next function is useful when the you have a large number of pages,
-and the tabs don't fit on the page. It allows the tabs to be scrolled
-through using two arrow buttons.
+<tt/xalign/ and <tt/yalign/ take values between 0.0 and 1.0. <tt/xalign/
+indicates the position of the label along the top horizontal of the
+frame. <tt/yalign/ is not currently used. The default value of xalign
+is 0.0 which places the label at the left hand end of the frame.
+
+The next function alters the style of the box that is used to outline
+the frame.
 
 <tscreen><verb>
-void gtk_notebook_set_scrollable( GtkNotebook *notebook,
-                                  gboolean     scrollable );
+void gtk_frame_set_shadow_type( GtkFrame      *frame,
+                                GtkShadowType  type);
 </verb></tscreen>
 
-<tt/show_tabs/, <tt/show_border/ and <tt/scrollable/ can be either
-TRUE or FALSE.
+The <tt/type/ argument can take one of the following values:
+<itemize>
+<item> GTK_SHADOW_NONE
+<item> GTK_SHADOW_IN
+<item> GTK_SHADOW_OUT
+<item> GTK_SHADOW_ETCHED_IN (the default)
+<item> GTK_SHADOW_ETCHED_OUT
+</itemize>
 
-Now lets look at an example, it is expanded from the testgtk.c code
-that comes with the GTK distribution. This small program creates a
-window with a notebook and six buttons. The notebook contains 11
-pages, added in three different ways, appended, inserted, and
-prepended. The buttons allow you rotate the tab positions, add/remove
-the tabs and border, remove a page, change pages in both a forward and
-backward manner, and exit the program.
+The following code example illustrates the use of the Frame widget.
 
 <tscreen><verb>
-/* example-start notebook notebook.c */
+/* example-start frame frame.c */
 
 #include <gtk/gtk.h>
 
-/* This function rotates the position of the tabs */
-void rotate_book (GtkButton *button, GtkNotebook *notebook)
+int main( int   argc,
+          char *argv[] )
 {
-    gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos +1) %4);
-}
+  /* GtkWidget is the storage type for widgets */
+  GtkWidget *window;
+  GtkWidget *frame;
+  GtkWidget *button;
+  gint i;
 
-/* Add/Remove the page tabs and the borders */
-void tabsborder_book (GtkButton *button, GtkNotebook *notebook)
-{
-    gint tval = FALSE;
-    gint bval = FALSE;
-    if (notebook->show_tabs == 0)
-           tval = TRUE; 
-    if (notebook->show_border == 0)
-           bval = TRUE;
+  /* Initialise GTK */
+  gtk_init(&amp;argc, &amp;argv);
     
-    gtk_notebook_set_show_tabs (notebook, tval);
-    gtk_notebook_set_show_border (notebook, bval);
-}
+  /* Create a new window */
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_window_set_title(GTK_WINDOW(window), "Frame Example");
 
-/* Remove a page from the notebook */
-void remove_book (GtkButton *button, GtkNotebook *notebook)
-{
-    gint page;
-    
-    page = gtk_notebook_get_current_page(notebook);
-    gtk_notebook_remove_page (notebook, page);
-    /* Need to refresh the widget -- 
-     This forces the widget to redraw itself. */
-    gtk_widget_draw(GTK_WIDGET(notebook), NULL);
-}
+  /* Here we connect the "destroy" event to a signal handler */ 
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
 
-void delete (GtkWidget *widget, GtkWidget *event, gpointer data)
-{
-    gtk_main_quit ();
-}
+  gtk_widget_set_usize(window, 300, 300);
+  /* Sets the border width of the window. */
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
 
-int main (int argc, char *argv[])
-{
-    GtkWidget *window;
-    GtkWidget *button;
-    GtkWidget *table;
-    GtkWidget *notebook;
-    GtkWidget *frame;
-    GtkWidget *label;
-    GtkWidget *checkbutton;
-    int i;
-    char bufferf[32];
-    char bufferl[32];
-    
-    gtk_init (&amp;argc, &amp;argv);
-    
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    
-    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
-                       GTK_SIGNAL_FUNC (delete), NULL);
-    
-    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+  /* Create a Frame */
+  frame = gtk_frame_new(NULL);
+  gtk_container_add(GTK_CONTAINER(window), frame);
 
-    table = gtk_table_new(3,6,FALSE);
-    gtk_container_add (GTK_CONTAINER (window), table);
-    
-    /* Create a new notebook, place the position of the tabs */
-    notebook = gtk_notebook_new ();
-    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
-    gtk_table_attach_defaults(GTK_TABLE(table), notebook, 0,6,0,1);
-    gtk_widget_show(notebook);
-    
-    /* Lets append a bunch of pages to the notebook */
-    for (i=0; i < 5; i++) {
-       sprintf(bufferf, "Append Frame %d", i+1);
-       sprintf(bufferl, "Page %d", i+1);
-       
-       frame = gtk_frame_new (bufferf);
-       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
-       gtk_widget_set_usize (frame, 100, 75);
-       gtk_widget_show (frame);
-       
-       label = gtk_label_new (bufferf);
-       gtk_container_add (GTK_CONTAINER (frame), label);
-       gtk_widget_show (label);
-       
-       label = gtk_label_new (bufferl);
-       gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
-    }
-      
-    /* Now lets add a page to a specific spot */
-    checkbutton = gtk_check_button_new_with_label ("Check me please!");
-    gtk_widget_set_usize(checkbutton, 100, 75);
-    gtk_widget_show (checkbutton);
-   
-    label = gtk_label_new ("Add page");
-    gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);
-    
-    /* Now finally lets prepend pages to the notebook */
-    for (i=0; i < 5; i++) {
-       sprintf(bufferf, "Prepend Frame %d", i+1);
-       sprintf(bufferl, "PPage %d", i+1);
-       
-       frame = gtk_frame_new (bufferf);
-       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
-       gtk_widget_set_usize (frame, 100, 75);
-       gtk_widget_show (frame);
-       
-       label = gtk_label_new (bufferf);
-       gtk_container_add (GTK_CONTAINER (frame), label);
-       gtk_widget_show (label);
-       
-       label = gtk_label_new (bufferl);
-       gtk_notebook_prepend_page (GTK_NOTEBOOK(notebook), frame, label);
-    }
-    
-    /* Set what page to start at (page 4) */
-    gtk_notebook_set_page (GTK_NOTEBOOK(notebook), 3);
+  /* Set the frames label */
+  gtk_frame_set_label( GTK_FRAME(frame), "GTK Frame Widget" );
 
-    /* Create a bunch of buttons */
-    button = gtk_button_new_with_label ("close");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              GTK_SIGNAL_FUNC (delete), NULL);
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("next page");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              (GtkSignalFunc) gtk_notebook_next_page,
-                              GTK_OBJECT (notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("prev page");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              (GtkSignalFunc) gtk_notebook_prev_page,
-                              GTK_OBJECT (notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 2,3,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("tab position");
-    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                        (GtkSignalFunc) rotate_book, GTK_OBJECT(notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 3,4,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("tabs/border on/off");
-    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                        (GtkSignalFunc) tabsborder_book,
-                        GTK_OBJECT (notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 4,5,1,2);
-    gtk_widget_show(button);
-    
-    button = gtk_button_new_with_label ("remove page");
-    gtk_signal_connect (GTK_OBJECT (button), "clicked",
-                        (GtkSignalFunc) remove_book,
-                        GTK_OBJECT(notebook));
-    gtk_table_attach_defaults(GTK_TABLE(table), button, 5,6,1,2);
-    gtk_widget_show(button);
-    
-    gtk_widget_show(table);
-    gtk_widget_show(window);
+  /* Align the label at the right of the frame */
+  gtk_frame_set_label_align( GTK_FRAME(frame), 1.0, 0.0);
+
+  /* Set the style of the frame */
+  gtk_frame_set_shadow_type( GTK_FRAME(frame), GTK_SHADOW_ETCHED_OUT);
+
+  gtk_widget_show(frame);
+  
+  /* Display the window */
+  gtk_widget_show (window);
     
-    gtk_main ();
+  /* Enter the event loop */
+  gtk_main ();
     
-    return(0);
+  return(0);
 }
 /* example-end */
-</verb></tscreen>
-
-Hopefully this helps you on your way with creating notebooks for your
-GTK applications.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1>Scrolled Windows
-<p>
-Scrolled windows are used to create a scrollable area inside a real
-window.  You may insert any type of widget into a scrolled window, and
-it will be accessible regardless of the size by using the scrollbars.
 
-The following function is used to create a new scrolled window.
-
-<tscreen><verb>
-GtkWidget *gtk_scrolled_window_new( GtkAdjustment *hadjustment,
-                                    GtkAdjustment *vadjustment );
 </verb></tscreen>
 
-Where the first argument is the adjustment for the horizontal
-direction, and the second, the adjustment for the vertical direction.
-These are almost always set to NULL.
-
+<!-- ----------------------------------------------------------------- -->   
+<sect1> Aspect Frames
+<p>
+The aspect frame widget is like a frame widget, except that it also
+enforces the aspect ratio (that is, the ratio of the width to the
+height) of the child widget to have a certain value, adding extra
+space if necessary. This is useful, for instance, if you want to
+preview a larger image. The size of the preview should vary when the
+user resizes the window, but the aspect ratio needs to always match
+the original image.
+  
+To create a new aspect frame use:
+   
 <tscreen><verb>
-void gtk_scrolled_window_set_policy( GtkScrolledWindow *scrolled_window,
-                                     GtkPolicyType      hscrollbar_policy,
-                                     GtkPolicyType      vscrollbar_policy );
+GtkWidget *gtk_aspect_frame_new( const gchar *label,
+                                 gfloat       xalign,
+                                 gfloat       yalign,
+                                 gfloat       ratio,
+                                 gint         obey_child);
 </verb></tscreen>
-
-This sets the policy to be used with respect to the scrollbars.
-The first argument is the scrolled window you wish to change. The second
-sets the policy for the horizontal scrollbar, and the third the policy for 
-the vertical scrollbar.
-
-The policy may be one of GTK_POLICY_AUTOMATIC, or GTK_POLICY_ALWAYS.
-GTK_POLICY_AUTOMATIC will automatically decide whether you need
-scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
-there.
-
-You can then place your object into the scrolled window using the
-following function.
-
+   
+<tt/xalign/ and <tt/yalign/ specify alignment as with Alignment
+widgets. If <tt/obey_child/ is true, the aspect ratio of a child
+widget will match the aspect ratio of the ideal size it requests.
+Otherwise, it is given by <tt/ratio/.
+   
+To change the options of an existing aspect frame, you can use:
+   
 <tscreen><verb>
-void gtk_scrolled_window_add_with_viewport( GtkScrolledWindow *scrolled_window,
-                                            GtkWidget         *child);
+void gtk_aspect_frame_set( GtkAspectFrame *aspect_frame,
+                           gfloat          xalign,
+                           gfloat          yalign,
+                           gfloat          ratio,
+                           gint            obey_child);
 </verb></tscreen>
-
-Here is a simple example that packs 100 toggle buttons into a scrolled
-window.  I've only commented on the parts that may be new to you.
-
+   
+As an example, the following program uses an AspectFrame to present a
+drawing area whose aspect ratio will always be 2:1, no matter how the
+user resizes the top-level window.
+   
 <tscreen><verb>
-/* example-start scrolledwin scrolledwin.c */
+/* example-start aspectframe aspectframe.c */
 
 #include <gtk/gtk.h>
-
-void destroy(GtkWidget *widget, gpointer data)
-{
-    gtk_main_quit();
-}
-
-int main (int argc, char *argv[])
+   
+int
+main (int argc, char *argv[])
 {
-    static GtkWidget *window;
-    GtkWidget *scrolled_window;
-    GtkWidget *table;
-    GtkWidget *button;
-    char buffer[32];
-    int i, j;
-    
+    GtkWidget *window;
+    GtkWidget *aspect_frame;
+    GtkWidget *drawing_area;
     gtk_init (&amp;argc, &amp;argv);
-    
-    /* Create a new dialog window for the scrolled window to be
-     * packed into. A dialog is just like a normal window except it has a 
-     * vbox and a horizontal separator packed into it. It's just a shortcut
-     * for creating dialogs */
-    window = gtk_dialog_new ();
+   
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
     gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                       (GtkSignalFunc) destroy, NULL);
-    gtk_window_set_title (GTK_WINDOW (window), "GtkScrolledWindow example");
-    gtk_container_set_border_width (GTK_CONTAINER (window), 0);
-    gtk_widget_set_usize(window, 300, 300);
-    
-    /* create a new scrolled window. */
-    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
-    
-    gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
-    
-    /* the policy is one of GTK_POLICY AUTOMATIC, or GTK_POLICY_ALWAYS.
-     * GTK_POLICY_AUTOMATIC will automatically decide whether you need
-     * scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
-     * there.  The first one is the horizontal scrollbar, the second, 
-     * the vertical. */
-    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
-                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
-    /* The dialog window is created with a vbox packed into it. */                                                             
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window, 
-                       TRUE, TRUE, 0);
-    gtk_widget_show (scrolled_window);
-    
-    /* create a table of 10 by 10 squares. */
-    table = gtk_table_new (10, 10, FALSE);
-    
-    /* set the spacing to 10 on x and 10 on y */
-    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
-    gtk_table_set_col_spacings (GTK_TABLE (table), 10);
-    
-    /* pack the table into the scrolled window */
-    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
-                                           table);
-    gtk_widget_show (table);
-    
-    /* this simply creates a grid of toggle buttons on the table
-     * to demonstrate the scrolled window. */
-    for (i = 0; i < 10; i++)
-       for (j = 0; j < 10; j++) {
-          sprintf (buffer, "button (%d,%d)\n", i, j);
-         button = gtk_toggle_button_new_with_label (buffer);
-         gtk_table_attach_defaults (GTK_TABLE (table), button,
-                                    i, i+1, j, j+1);
-          gtk_widget_show (button);
-       }
-    
-    /* Add a "close" button to the bottom of the dialog */
-    button = gtk_button_new_with_label ("close");
-    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                              (GtkSignalFunc) gtk_widget_destroy,
-                              GTK_OBJECT (window));
-    
-    /* this makes it so the button is the default. */
-    
-    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
-    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
-    
-    /* This grabs this button to be the default button. Simply hitting
-     * the "Enter" key will cause this button to activate. */
-    gtk_widget_grab_default (button);
-    gtk_widget_show (button);
-    
+                        GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
+    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+   
+    /* Create an aspect_frame and add it to our toplevel window */
+   
+    aspect_frame = gtk_aspect_frame_new ("2x1", /* label */
+                                         0.5, /* center x */
+                                         0.5, /* center y */
+                                         2, /* xsize/ysize = 2 */
+                                         FALSE /* ignore child's aspect */);
+   
+    gtk_container_add (GTK_CONTAINER(window), aspect_frame);
+    gtk_widget_show (aspect_frame);
+   
+    /* Now add a child widget to the aspect frame */
+   
+    drawing_area = gtk_drawing_area_new ();
+   
+    /* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
+     * window since we are forcing a 2x1 aspect ratio */
+    gtk_widget_set_usize (drawing_area, 200, 200);
+    gtk_container_add (GTK_CONTAINER(aspect_frame), drawing_area);
+    gtk_widget_show (drawing_area);
+   
     gtk_widget_show (window);
-    
-    gtk_main();
-    
-    return(0);
+    gtk_main ();
+    return 0;
 }
 /* example-end */
 </verb></tscreen>
 
-Try playing with resizing the window. You'll notice how the scrollbars
-react. You may also wish to use the gtk_widget_set_usize() call to set
-the default size of the window or other widgets.
-
 <!-- ----------------------------------------------------------------- -->   
 <sect1> Paned Window Widgets
 <p>
@@ -5451,6 +5389,152 @@ main (int argc, char *argv[])
 /* example-end */
 </verb></tscreen>
 
+<!-- ----------------------------------------------------------------- -->
+<sect1>Scrolled Windows
+<p>
+Scrolled windows are used to create a scrollable area inside a real
+window.  You may insert any type of widget into a scrolled window, and
+it will be accessible regardless of the size by using the scrollbars.
+
+The following function is used to create a new scrolled window.
+
+<tscreen><verb>
+GtkWidget *gtk_scrolled_window_new( GtkAdjustment *hadjustment,
+                                    GtkAdjustment *vadjustment );
+</verb></tscreen>
+
+Where the first argument is the adjustment for the horizontal
+direction, and the second, the adjustment for the vertical direction.
+These are almost always set to NULL.
+
+<tscreen><verb>
+void gtk_scrolled_window_set_policy( GtkScrolledWindow *scrolled_window,
+                                     GtkPolicyType      hscrollbar_policy,
+                                     GtkPolicyType      vscrollbar_policy );
+</verb></tscreen>
+
+This sets the policy to be used with respect to the scrollbars.
+The first argument is the scrolled window you wish to change. The second
+sets the policy for the horizontal scrollbar, and the third the policy for 
+the vertical scrollbar.
+
+The policy may be one of GTK_POLICY_AUTOMATIC, or GTK_POLICY_ALWAYS.
+GTK_POLICY_AUTOMATIC will automatically decide whether you need
+scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
+there.
+
+You can then place your object into the scrolled window using the
+following function.
+
+<tscreen><verb>
+void gtk_scrolled_window_add_with_viewport( GtkScrolledWindow *scrolled_window,
+                                            GtkWidget         *child);
+</verb></tscreen>
+
+Here is a simple example that packs 100 toggle buttons into a scrolled
+window.  I've only commented on the parts that may be new to you.
+
+<tscreen><verb>
+/* example-start scrolledwin scrolledwin.c */
+
+#include <gtk/gtk.h>
+
+void destroy(GtkWidget *widget, gpointer data)
+{
+    gtk_main_quit();
+}
+
+int main (int argc, char *argv[])
+{
+    static GtkWidget *window;
+    GtkWidget *scrolled_window;
+    GtkWidget *table;
+    GtkWidget *button;
+    char buffer[32];
+    int i, j;
+    
+    gtk_init (&amp;argc, &amp;argv);
+    
+    /* Create a new dialog window for the scrolled window to be
+     * packed into. A dialog is just like a normal window except it has a 
+     * vbox and a horizontal separator packed into it. It's just a shortcut
+     * for creating dialogs */
+    window = gtk_dialog_new ();
+    gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                       (GtkSignalFunc) destroy, NULL);
+    gtk_window_set_title (GTK_WINDOW (window), "GtkScrolledWindow example");
+    gtk_container_set_border_width (GTK_CONTAINER (window), 0);
+    gtk_widget_set_usize(window, 300, 300);
+    
+    /* create a new scrolled window. */
+    scrolled_window = gtk_scrolled_window_new (NULL, NULL);
+    
+    gtk_container_set_border_width (GTK_CONTAINER (scrolled_window), 10);
+    
+    /* the policy is one of GTK_POLICY AUTOMATIC, or GTK_POLICY_ALWAYS.
+     * GTK_POLICY_AUTOMATIC will automatically decide whether you need
+     * scrollbars, whereas GTK_POLICY_ALWAYS will always leave the scrollbars
+     * there.  The first one is the horizontal scrollbar, the second, 
+     * the vertical. */
+    gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_window),
+                                    GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
+    /* The dialog window is created with a vbox packed into it. */                                                             
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG(window)->vbox), scrolled_window, 
+                       TRUE, TRUE, 0);
+    gtk_widget_show (scrolled_window);
+    
+    /* create a table of 10 by 10 squares. */
+    table = gtk_table_new (10, 10, FALSE);
+    
+    /* set the spacing to 10 on x and 10 on y */
+    gtk_table_set_row_spacings (GTK_TABLE (table), 10);
+    gtk_table_set_col_spacings (GTK_TABLE (table), 10);
+    
+    /* pack the table into the scrolled window */
+    gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled_window),
+                                           table);
+    gtk_widget_show (table);
+    
+    /* this simply creates a grid of toggle buttons on the table
+     * to demonstrate the scrolled window. */
+    for (i = 0; i < 10; i++)
+       for (j = 0; j < 10; j++) {
+          sprintf (buffer, "button (%d,%d)\n", i, j);
+         button = gtk_toggle_button_new_with_label (buffer);
+         gtk_table_attach_defaults (GTK_TABLE (table), button,
+                                    i, i+1, j, j+1);
+          gtk_widget_show (button);
+       }
+    
+    /* Add a "close" button to the bottom of the dialog */
+    button = gtk_button_new_with_label ("close");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              (GtkSignalFunc) gtk_widget_destroy,
+                              GTK_OBJECT (window));
+    
+    /* this makes it so the button is the default. */
+    
+    GTK_WIDGET_SET_FLAGS (button, GTK_CAN_DEFAULT);
+    gtk_box_pack_start (GTK_BOX (GTK_DIALOG (window)->action_area), button, TRUE, TRUE, 0);
+    
+    /* This grabs this button to be the default button. Simply hitting
+     * the "Enter" key will cause this button to activate. */
+    gtk_widget_grab_default (button);
+    gtk_widget_show (button);
+    
+    gtk_widget_show (window);
+    
+    gtk_main();
+    
+    return(0);
+}
+/* example-end */
+</verb></tscreen>
+
+Try playing with resizing the window. You'll notice how the scrollbars
+react. You may also wish to use the gtk_widget_set_usize() call to set
+the default size of the window or other widgets.
+
 <!-- ----------------------------------------------------------------- -->   
 <sect1>Toolbar
 <p>
@@ -5884,226 +5968,364 @@ static char * gtk_xpm[] = {
 ".............++++..............."};
 </verb></tscreen>
 
-<!-- ----------------------------------------------------------------- -->   
-<sect1> Aspect Frames
+<!-- ----------------------------------------------------------------- -->
+<sect1> Notebooks
 <p>
-The aspect frame widget is like a frame widget, except that it also
-enforces the aspect ratio (that is, the ratio of the width to the
-height) of the child widget to have a certain value, adding extra
-space if necessary. This is useful, for instance, if you want to
-preview a larger image. The size of the preview should vary when the
-user resizes the window, but the aspect ratio needs to always match
-the original image.
-  
-To create a new aspect frame use:
-   
-<tscreen><verb>
-GtkWidget *gtk_aspect_frame_new( const gchar *label,
-                                 gfloat       xalign,
-                                 gfloat       yalign,
-                                 gfloat       ratio,
-                                 gint         obey_child);
-</verb></tscreen>
-   
-<tt/xalign/ and <tt/yalign/ specify alignment as with Alignment
-widgets. If <tt/obey_child/ is true, the aspect ratio of a child
-widget will match the aspect ratio of the ideal size it requests.
-Otherwise, it is given by <tt/ratio/.
-   
-To change the options of an existing aspect frame, you can use:
-   
+The NoteBook Widget is a collection of 'pages' that overlap each
+other, each page contains different information. This widget has
+become more common lately in GUI programming, and it is a good way to
+show blocks of similar information that warrant separation in their
+display.
+
+The first function call you will need to know, as you can probably
+guess by now, is used to create a new notebook widget.
+
 <tscreen><verb>
-void gtk_aspect_frame_set( GtkAspectFrame *aspect_frame,
-                           gfloat          xalign,
-                           gfloat          yalign,
-                           gfloat          ratio,
-                           gint            obey_child);
+GtkWidget *gtk_notebook_new( void );
 </verb></tscreen>
-   
-As an example, the following program uses an AspectFrame to present a
-drawing area whose aspect ratio will always be 2:1, no matter how the
-user resizes the top-level window.
-   
-<tscreen><verb>
-/* example-start aspectframe aspectframe.c */
 
-#include <gtk/gtk.h>
-   
-int
-main (int argc, char *argv[])
-{
-    GtkWidget *window;
-    GtkWidget *aspect_frame;
-    GtkWidget *drawing_area;
-    gtk_init (&amp;argc, &amp;argv);
-   
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
-    gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                        GTK_SIGNAL_FUNC (gtk_main_quit), NULL);
-    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
-   
-    /* Create an aspect_frame and add it to our toplevel window */
-   
-    aspect_frame = gtk_aspect_frame_new ("2x1", /* label */
-                                         0.5, /* center x */
-                                         0.5, /* center y */
-                                         2, /* xsize/ysize = 2 */
-                                         FALSE /* ignore child's aspect */);
-   
-    gtk_container_add (GTK_CONTAINER(window), aspect_frame);
-    gtk_widget_show (aspect_frame);
-   
-    /* Now add a child widget to the aspect frame */
-   
-    drawing_area = gtk_drawing_area_new ();
-   
-    /* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
-     * window since we are forcing a 2x1 aspect ratio */
-    gtk_widget_set_usize (drawing_area, 200, 200);
-    gtk_container_add (GTK_CONTAINER(aspect_frame), drawing_area);
-    gtk_widget_show (drawing_area);
-   
-    gtk_widget_show (window);
-    gtk_main ();
-    return 0;
-}
-/* example-end */
+Once the notebook has been created, there are a number of functions
+that operate on the notebook widget. Let's look at them individually.
+
+The first one we will look at is how to position the page indicators.
+These page indicators or 'tabs' as they are referred to, can be
+positioned in four ways: top, bottom, left, or right.
+
+<tscreen><verb>
+void gtk_notebook_set_tab_pos( GtkNotebook     *notebook,
+                               GtkPositionType  pos );
 </verb></tscreen>
 
-<!-- ----------------------------------------------------------------- -->   
-<sect1>The EventBox <label id="sec_EventBox">
-<p> 
-Some gtk widgets don't have associated X windows, so they just draw on
-their parents. Because of this, they cannot receive events and if they
-are incorrectly sized, they don't clip so you can get messy
-overwriting etc. If you require more from these widgets, the EventBox
-is for you.
+GtkPostionType will be one of the following, and they are pretty self explanatory:
+<itemize>
+<item> GTK_POS_LEFT
+<item> GTK_POS_RIGHT
+<item> GTK_POS_TOP
+<item> GTK_POS_BOTTOM
+</itemize>
 
-At first glance, the EventBox widget might appear to be totally
-useless. It draws nothing on the screen and responds to no
-events. However, it does serve a function - it provides an X window
-for its child widget. This is important as many GTK widgets do not
-have an associated X window. Not having an X window saves memory and
-improves performance, but also has some drawbacks. A widget without an
-X window cannot receive events, and does not perform any clipping on
-its contents. Although the name <em/EventBox/ emphasizes the
-event-handling function, the widget can also be used for clipping.
-(and more, see the example below).
+GTK_POS_TOP is the default.
 
-To create a new EventBox widget, use:
+Next we will look at how to add pages to the notebook. There are three
+ways to add pages to the NoteBook. Let's look at the first two
+together as they are quite similar.
 
 <tscreen><verb>
-GtkWidget *gtk_event_box_new( void );
+void gtk_notebook_append_page( GtkNotebook *notebook,
+                               GtkWidget   *child,
+                               GtkWidget   *tab_label );
+
+void gtk_notebook_prepend_page( GtkNotebook *notebook,
+                                GtkWidget   *child,
+                                GtkWidget   *tab_label );
 </verb></tscreen>
 
-A child widget can then be added to this EventBox:
+These functions add pages to the notebook by inserting them from the
+back of the notebook (append), or the front of the notebook (prepend).
+<tt/child/ is the widget that is placed within the notebook page, and
+<tt/tab_label/ is the label for the page being added. The <tt/child/
+widget must be created separately, and is typically a set of options
+setout witin one of the other container widgets, such as a table.
+
+The final function for adding a page to the notebook contains all of
+the properties of the previous two, but it allows you to specify what
+position you want the page to be in the notebook.
 
 <tscreen><verb>
-gtk_container_add( GTK_CONTAINER(event_box), widget );
+void gtk_notebook_insert_page( GtkNotebook *notebook,
+                               GtkWidget   *child,
+                               GtkWidget   *tab_label,
+                               gint         position );
 </verb></tscreen>
 
-The following example demonstrates both uses of an EventBox - a label
-is created that is clipped to a small box, and set up so that a
-mouse-click on the label causes the program to exit. Resizing the
-window reveals varying amounts of the label.
-
-<tscreen><verb>
-/* example-start eventbox eventbox.c */
+The parameters are the same as _append_ and _prepend_ except it
+contains an extra parameter, <tt/position/.  This parameter is used to
+specify what place this page will be inserted into.
 
-#include <gtk/gtk.h>
+Now that we know how to add a page, lets see how we can remove a page
+from the notebook.
 
-int 
-main (int argc, char *argv[])
-{
-    GtkWidget *window;
-    GtkWidget *event_box;
-    GtkWidget *label;
-    
-    gtk_init (&amp;argc, &amp;argv);
-    
-    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-    
-    gtk_window_set_title (GTK_WINDOW (window), "Event Box");
-    
-    gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
-    
-    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
-    
-    /* Create an EventBox and add it to our toplevel window */
-    
-    event_box = gtk_event_box_new ();
-    gtk_container_add (GTK_CONTAINER(window), event_box);
-    gtk_widget_show (event_box);
-    
-    /* Create a long label */
-    
-    label = gtk_label_new ("Click here to quit, quit, quit, quit, quit");
-    gtk_container_add (GTK_CONTAINER (event_box), label);
-    gtk_widget_show (label);
-    
-    /* Clip it short. */
-    gtk_widget_set_usize (label, 110, 20);
-    
-    /* And bind an action to it */
-    gtk_widget_set_events (event_box, GDK_BUTTON_PRESS_MASK);
-    gtk_signal_connect (GTK_OBJECT(event_box), "button_press_event",
-                       GTK_SIGNAL_FUNC (gtk_exit), NULL);
-    
-    /* Yet one more thing you need an X window for ... */
-    
-    gtk_widget_realize (event_box);
-    gdk_window_set_cursor (event_box->window, gdk_cursor_new (GDK_HAND1));
-    
-    gtk_widget_show (window);
-    
-    gtk_main ();
-    
-    return(0);
-}
-/* example-end */
+<tscreen><verb>
+void gtk_notebook_remove_page( GtkNotebook *notebook,
+                               gint         page_num );
 </verb></tscreen>
 
-<!-- ***************************************************************** -->
-<sect>CList Widget
-<!-- ***************************************************************** -->
-
-<!-- ----------------------------------------------------------------- -->
-<p>
-The GtkCList widget has replaced the GtkList widget (which is still
-available).
+This function takes the page specified by <tt/page_num/ and removes it
+from the widget pointed to by <tt/notebook/.
 
-The GtkCList widget is a multi-column list widget that is capable of
-handling literally thousands of rows of information. Each column can
-optionally have a title, which itself is optionally active, allowing
-us to bind a function to its selection.
+To find out what the current page is in a notebook use the function:
 
-<!-- ----------------------------------------------------------------- -->
-<sect1>Creating a GtkCList widget
-<p>
-Creating a GtkCList is quite straightforward, once you have learned
-about widgets in general. It provides the almost standard two ways,
-that is the hard way, and the easy way. But before we create it, there
-is one thing we should figure out beforehand: how many columns should
-it have?
+<tscreen><verb>
+gint gtk_notebook_get_current_page( GtkNotebook *notebook );
+</verb></tscreen>
 
-Not all columns have to be visible and can be used to store data that
-is related to a certain cell in the list.
+These next two functions are simple calls to move the notebook page
+forward or backward. Simply provide the respective function call with
+the notebook widget you wish to operate on. Note: when the NoteBook is
+currently on the last page, and gtk_notebook_next_page is called, the
+notebook will wrap back to the first page. Likewise, if the NoteBook
+is on the first page, and gtk_notebook_prev_page is called, the
+notebook will wrap to the last page.
 
 <tscreen><verb>
-GtkWidget *gtk_clist_new ( gint columns );
+void gtk_notebook_next_page( GtkNoteBook *notebook );
 
-GtkWidget *gtk_clist_new_with_titles( gint   columns,
-                                      gchar *titles[] );
+void gtk_notebook_prev_page( GtkNoteBook *notebook );
 </verb></tscreen>
 
-The first form is very straight forward, the second might require some
-explanation. Each column can have a title associated with it, and this
-title can be a label or a button that reacts when we click on it. If
-we use the second form, we must provide pointers to the title texts,
-and the number of pointers should equal the number of columns
-specified. Of course we can always use the first form, and manually
+This next function sets the 'active' page. If you wish the notebook to
+be opened to page 5 for example, you would use this function.  Without
+using this function, the notebook defaults to the first page.
+
+<tscreen><verb>
+void gtk_notebook_set_page( GtkNotebook *notebook,
+                            gint         page_num );
+</verb></tscreen>
+
+The next two functions add or remove the notebook page tabs and the
+notebook border respectively.
+
+<tscreen><verb>
+void gtk_notebook_set_show_tabs( GtkNotebook *notebook,
+                                 gboolean     show_tabs);
+
+void gtk_notebook_set_show_border( GtkNotebook *notebook,
+                                   gboolean     show_border );
+</verb></tscreen>
+
+The next function is useful when the you have a large number of pages,
+and the tabs don't fit on the page. It allows the tabs to be scrolled
+through using two arrow buttons.
+
+<tscreen><verb>
+void gtk_notebook_set_scrollable( GtkNotebook *notebook,
+                                  gboolean     scrollable );
+</verb></tscreen>
+
+<tt/show_tabs/, <tt/show_border/ and <tt/scrollable/ can be either
+TRUE or FALSE.
+
+Now lets look at an example, it is expanded from the testgtk.c code
+that comes with the GTK distribution. This small program creates a
+window with a notebook and six buttons. The notebook contains 11
+pages, added in three different ways, appended, inserted, and
+prepended. The buttons allow you rotate the tab positions, add/remove
+the tabs and border, remove a page, change pages in both a forward and
+backward manner, and exit the program.
+
+<tscreen><verb>
+/* example-start notebook notebook.c */
+
+#include <gtk/gtk.h>
+
+/* This function rotates the position of the tabs */
+void rotate_book (GtkButton *button, GtkNotebook *notebook)
+{
+    gtk_notebook_set_tab_pos (notebook, (notebook->tab_pos +1) %4);
+}
+
+/* Add/Remove the page tabs and the borders */
+void tabsborder_book (GtkButton *button, GtkNotebook *notebook)
+{
+    gint tval = FALSE;
+    gint bval = FALSE;
+    if (notebook->show_tabs == 0)
+           tval = TRUE; 
+    if (notebook->show_border == 0)
+           bval = TRUE;
+    
+    gtk_notebook_set_show_tabs (notebook, tval);
+    gtk_notebook_set_show_border (notebook, bval);
+}
+
+/* Remove a page from the notebook */
+void remove_book (GtkButton *button, GtkNotebook *notebook)
+{
+    gint page;
+    
+    page = gtk_notebook_get_current_page(notebook);
+    gtk_notebook_remove_page (notebook, page);
+    /* Need to refresh the widget -- 
+     This forces the widget to redraw itself. */
+    gtk_widget_draw(GTK_WIDGET(notebook), NULL);
+}
+
+void delete (GtkWidget *widget, GtkWidget *event, gpointer data)
+{
+    gtk_main_quit ();
+}
+
+int main (int argc, char *argv[])
+{
+    GtkWidget *window;
+    GtkWidget *button;
+    GtkWidget *table;
+    GtkWidget *notebook;
+    GtkWidget *frame;
+    GtkWidget *label;
+    GtkWidget *checkbutton;
+    int i;
+    char bufferf[32];
+    char bufferl[32];
+    
+    gtk_init (&amp;argc, &amp;argv);
+    
+    window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+    
+    gtk_signal_connect (GTK_OBJECT (window), "delete_event",
+                       GTK_SIGNAL_FUNC (delete), NULL);
+    
+    gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+    table = gtk_table_new(3,6,FALSE);
+    gtk_container_add (GTK_CONTAINER (window), table);
+    
+    /* Create a new notebook, place the position of the tabs */
+    notebook = gtk_notebook_new ();
+    gtk_notebook_set_tab_pos (GTK_NOTEBOOK (notebook), GTK_POS_TOP);
+    gtk_table_attach_defaults(GTK_TABLE(table), notebook, 0,6,0,1);
+    gtk_widget_show(notebook);
+    
+    /* Lets append a bunch of pages to the notebook */
+    for (i=0; i < 5; i++) {
+       sprintf(bufferf, "Append Frame %d", i+1);
+       sprintf(bufferl, "Page %d", i+1);
+       
+       frame = gtk_frame_new (bufferf);
+       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+       gtk_widget_set_usize (frame, 100, 75);
+       gtk_widget_show (frame);
+       
+       label = gtk_label_new (bufferf);
+       gtk_container_add (GTK_CONTAINER (frame), label);
+       gtk_widget_show (label);
+       
+       label = gtk_label_new (bufferl);
+       gtk_notebook_append_page (GTK_NOTEBOOK (notebook), frame, label);
+    }
+      
+    /* Now lets add a page to a specific spot */
+    checkbutton = gtk_check_button_new_with_label ("Check me please!");
+    gtk_widget_set_usize(checkbutton, 100, 75);
+    gtk_widget_show (checkbutton);
+   
+    label = gtk_label_new ("Add page");
+    gtk_notebook_insert_page (GTK_NOTEBOOK (notebook), checkbutton, label, 2);
+    
+    /* Now finally lets prepend pages to the notebook */
+    for (i=0; i < 5; i++) {
+       sprintf(bufferf, "Prepend Frame %d", i+1);
+       sprintf(bufferl, "PPage %d", i+1);
+       
+       frame = gtk_frame_new (bufferf);
+       gtk_container_set_border_width (GTK_CONTAINER (frame), 10);
+       gtk_widget_set_usize (frame, 100, 75);
+       gtk_widget_show (frame);
+       
+       label = gtk_label_new (bufferf);
+       gtk_container_add (GTK_CONTAINER (frame), label);
+       gtk_widget_show (label);
+       
+       label = gtk_label_new (bufferl);
+       gtk_notebook_prepend_page (GTK_NOTEBOOK(notebook), frame, label);
+    }
+    
+    /* Set what page to start at (page 4) */
+    gtk_notebook_set_page (GTK_NOTEBOOK(notebook), 3);
+
+    /* Create a bunch of buttons */
+    button = gtk_button_new_with_label ("close");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              GTK_SIGNAL_FUNC (delete), NULL);
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 0,1,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("next page");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              (GtkSignalFunc) gtk_notebook_next_page,
+                              GTK_OBJECT (notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 1,2,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("prev page");
+    gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                              (GtkSignalFunc) gtk_notebook_prev_page,
+                              GTK_OBJECT (notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 2,3,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("tab position");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                        (GtkSignalFunc) rotate_book, GTK_OBJECT(notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 3,4,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("tabs/border on/off");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                        (GtkSignalFunc) tabsborder_book,
+                        GTK_OBJECT (notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 4,5,1,2);
+    gtk_widget_show(button);
+    
+    button = gtk_button_new_with_label ("remove page");
+    gtk_signal_connect (GTK_OBJECT (button), "clicked",
+                        (GtkSignalFunc) remove_book,
+                        GTK_OBJECT(notebook));
+    gtk_table_attach_defaults(GTK_TABLE(table), button, 5,6,1,2);
+    gtk_widget_show(button);
+    
+    gtk_widget_show(table);
+    gtk_widget_show(window);
+    
+    gtk_main ();
+    
+    return(0);
+}
+/* example-end */
+</verb></tscreen>
+
+Hopefully this helps you on your way with creating notebooks for your
+GTK applications.
+
+<!-- ***************************************************************** -->
+<sect>CList Widget
+<!-- ***************************************************************** -->
+
+<!-- ----------------------------------------------------------------- -->
+<p>
+The GtkCList widget has replaced the GtkList widget (which is still
+available).
+
+The GtkCList widget is a multi-column list widget that is capable of
+handling literally thousands of rows of information. Each column can
+optionally have a title, which itself is optionally active, allowing
+us to bind a function to its selection.
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Creating a GtkCList widget
+<p>
+Creating a GtkCList is quite straightforward, once you have learned
+about widgets in general. It provides the almost standard two ways,
+that is the hard way, and the easy way. But before we create it, there
+is one thing we should figure out beforehand: how many columns should
+it have?
+
+Not all columns have to be visible and can be used to store data that
+is related to a certain cell in the list.
+
+<tscreen><verb>
+GtkWidget *gtk_clist_new ( gint columns );
+
+GtkWidget *gtk_clist_new_with_titles( gint   columns,
+                                      gchar *titles[] );
+</verb></tscreen>
+
+The first form is very straight forward, the second might require some
+explanation. Each column can have a title associated with it, and this
+title can be a label or a button that reacts when we click on it. If
+we use the second form, we must provide pointers to the title texts,
+and the number of pointers should equal the number of columns
+specified. Of course we can always use the first form, and manually
 add titles later.
 
 Note: the GtkCList widget does not have it's own scrollbars and should
@@ -6781,1059 +7003,446 @@ void selection_made( GtkWidget *clist, gint row, gint column,
 </verb></tscreen>
                     
 <!-- ***************************************************************** -->
-<sect> List Widget
+<sect> Tree Widget<label id="sec_Tree_Widgets">
 <!-- ***************************************************************** -->
 <p>
-NOTE: The GtkList widget has been superseded by the GtkCList widget.
-
-The GtkList widget is designed to act as a vertical container for
-widgets that should be of the type GtkListItem.
+The purpose of tree widgets is to display hierarchically-organized
+data. The GtkTree widget itself is a vertical container for widgets of
+type GtkTreeItem. GtkTree itself is not terribly different from
+GtkList - both are derived directly from GtkContainer, and the
+GtkContainer methods work in the same way on GtkTree widgets as on
+GtkList widgets. The difference is that GtkTree widgets can be nested
+within other GtkTree widgets. We'll see how to do this shortly.
 
-A GtkList widget has its own window to receive events and its own
-background color which is usually white. As it is directly derived
-from a GtkContainer it can be treated as such by using the
-GTK_CONTAINER(List) macro, see the GtkContainer widget for more on
-this. One should already be familiar with the usage of a GList and
-its related functions g_list_*() to be able to use the GtkList widget
-to it full extent.
+The GtkTree widget has its own window, and defaults to a white
+background, as does GtkList. Also, most of the GtkTree methods work in
+the same way as the corresponding GtkList ones. However, GtkTree is
+not derived from GtkList, so you cannot use them interchangeably.
 
-There is one field inside the structure definition of the GtkList
-widget that will be of greater interest to us, this is:
+<sect1> Creating a Tree
+<p>
+A GtkTree is created in the usual way, using:
 
 <tscreen><verb>
-struct _GtkList
-{
-  ...
-  GList *selection;
-  guint selection_mode;
-  ...
-}; 
+GtkWidget* gtk_tree_new( void );
 </verb></tscreen>
 
-The selection field of a GtkList points to a linked list of all items
-that are currently selected, or NULL if the selection is empty.  So to
-learn about the current selection we read the GTK_LIST()->selection
-field, but do not modify it since the internal fields are maintained
-by the gtk_list_*() functions.
+Like the GtkList widget, a GtkTree will simply keep growing as more
+items are added to it, as well as when subtrees are expanded.  For
+this reason, they are almost always packed into a
+GtkScrolledWindow. You might want to use gtk_widget_set_usize() on the
+scrolled window to ensure that it is big enough to see the tree's
+items, as the default size for GtkScrolledWindow is quite small.
 
-The selection_mode of the GtkList determines the selection facilities
-of a GtkList and therefore the contents of the GTK_LIST()->selection
-field. The selection_mode may be one of the following:
+Now that you have a tree, you'll probably want to add some items to
+it.  <ref id="sec_Tree_Item_Widget" name="The Tree Item Widget"> below
+explains the gory details of GtkTreeItem. For now, it'll suffice to
+create one, using:
 
-<itemize>
-<item> GTK_SELECTION_SINGLE - The selection is either NULL
-                        or contains a GList pointer
-                        for a single selected item.
+<tscreen><verb>
+GtkWidget* gtk_tree_item_new_with_label( gchar *label );
+</verb></tscreen>
 
-<item> GTK_SELECTION_BROWSE -  The selection is NULL if the list
-                        contains no widgets or insensitive
-                        ones only, otherwise it contains
-                        a GList pointer for one GList
-                        structure, and therefore exactly
-                        one list item.
+You can then add it to the tree using one of the following (see
+<ref id="sec_GtkTree_Functions" name="Functions and Macros">
+below for more options):
 
-<item> GTK_SELECTION_MULTIPLE -  The selection is NULL if no list
-                        items are selected or a GList pointer
-                        for the first selected item. That
-                        in turn points to a GList structure
-                        for the second selected item and so
-                        on.
+<tscreen><verb>
+void gtk_tree_append( GtkTree    *tree,
+                       GtkWidget *tree_item );
 
-<item> GTK_SELECTION_EXTENDED - The selection is always NULL.
-</itemize>
+void gtk_tree_prepend( GtkTree   *tree,
+                       GtkWidget *tree_item );
+</verb></tscreen>
 
-The default is GTK_SELECTION_MULTIPLE.
+Note that you must add items to a GtkTree one at a time - there is no
+equivalent to gtk_list_*_items().
 
 <!-- ----------------------------------------------------------------- -->
-<sect1> Signals
+<sect1> Adding a Subtree
 <p>
+A subtree is created like any other GtkTree widget. A subtree is added
+to another tree beneath a tree item, using:
+
 <tscreen><verb>
-void selection_changed( GtkList *list );
+void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,
+                                GtkWidget   *subtree );
 </verb></tscreen>
 
-This signal will be invoked whenever the selection field of a GtkList
-has changed. This happens when a child of the GtkList got selected or
-deselected.
+You do not need to call gtk_widget_show() on a subtree before or after
+adding it to a GtkTreeItem. However, you <em>must</em> have added the
+GtkTreeItem in question to a parent tree before calling
+gtk_tree_item_set_subtree(). This is because, technically, the parent
+of the subtree is <em>not</em> the GtkTreeItem which "owns" it, but
+rather the GtkTree which holds that GtkTreeItem.
 
-<tscreen><verb>
-void select_child( GtkList   *list,
-                   GtkWidget *child);
-</verb></tscreen>
+When you add a subtree to a GtkTreeItem, a plus or minus sign appears
+beside it, which the user can click on to "expand" or "collapse" it,
+meaning, to show or hide its subtree. GtkTreeItems are collapsed by
+default. Note that when you collapse a GtkTreeItem, any selected
+items in its subtree remain selected, which may not be what the user
+expects.
 
-This signal is invoked when a child of the GtkList is about to get
-selected. This happens mainly on calls to gtk_list_select_item(),
-gtk_list_select_child(), button presses and sometimes indirectly
-triggered on some else occasions where children get added to or
-removed from the GtkList.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Handling the Selection List
+<p>
+As with GtkList, the GtkTree type has a <tt>selection</tt> field, and
+it is possible to control the behaviour of the tree (somewhat) by
+setting the selection type using:
 
 <tscreen><verb>
-void unselect_child( GtkList   *list,
-                     GtkWidget *child );
+void gtk_tree_set_selection_mode( GtkTree          *tree,
+                                  GtkSelectionMode  mode );
 </verb></tscreen>
 
-This signal is invoked when a child of the GtkList is about to get
-deselected. This happens mainly on calls to gtk_list_unselect_item(),
-gtk_list_unselect_child(), button presses and sometimes indirectly
-triggered on some else occasions where children get added to or
-removed from the GtkList.
+The semantics associated with the various selection modes are
+described in the section on the GtkList widget. As with the GtkList
+widget, the "select_child", "unselect_child" (not really - see <ref
+id="sec_GtkTree_Signals" name="Signals"> below for an explanation),
+and "selection_changed" signals are emitted when list items are
+selected or unselected. However, in order to take advantage of these
+signals, you need to know <em>which</em> GtkTree widget they will be
+emitted by, and where to find the list of selected items.
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> Functions
+This is a source of potential confusion. The best way to explain this
+is that though all GtkTree widgets are created equal, some are more
+equal than others. All GtkTree widgets have their own X window, and
+can therefore receive events such as mouse clicks (if their
+GtkTreeItems or their children don't catch them first!). However, to
+make GTK_SELECTION_SINGLE and GTK_SELECTION_BROWSE selection types
+behave in a sane manner, the list of selected items is specific to the
+topmost GtkTree widget in a hierarchy, known as the "root tree".
+
+Thus, accessing the <tt>selection</tt>field directly in an arbitrary
+GtkTree widget is not a good idea unless you <em>know</em> it's the
+root tree.  Instead, use the GTK_TREE_SELECTION (Tree) macro, which
+gives the root tree's selection list as a GList pointer. Of course,
+this list can include items that are not in the subtree in question if 
+the selection type is GTK_SELECTION_MULTIPLE.
+
+Finally, the "select_child" (and "unselect_child", in theory) signals
+are emitted by all trees, but the "selection_changed" signal is only
+emitted by the root tree. Consequently, if you want to handle the
+"select_child" signal for a tree and all its subtrees, you will have
+to call gtk_signal_connect() for every subtree.
+
+<sect1> Tree Widget Internals
 <p>
+The GtkTree's struct definition looks like this:
+
 <tscreen><verb>
-guint gtk_list_get_type( void );
+struct _GtkTree
+{
+  GtkContainer container;
+
+  GList *children;
+  
+  GtkTree* root_tree; /* owner of selection list */
+  GtkWidget* tree_owner;
+  GList *selection;
+  guint level;
+  guint indent_value;
+  guint current_indent;
+  guint selection_mode : 2;
+  guint view_mode : 1;
+  guint view_line : 1;
+};
 </verb></tscreen>
 
-Returns the `GtkList' type identifier.
+The perils associated with accessing the <tt>selection</tt> field
+directly have already been mentioned. The other important fields of
+the struct can also be accessed with handy macros or class functions.
+GTK_TREE_IS_ROOT_TREE (Tree) returns a boolean value which indicates
+whether a tree is the root tree in a GtkTree hierarchy, while
+GTK_TREE_ROOT_TREE (Tree) returns the root tree, an object of type
+GtkTree (so, remember to cast it using GTK_WIDGET (Tree) if you want
+to use one of the gtk_widget_*() functions on it).
+
+Instead of directly accessing the children field of a GtkTree widget,
+it's probably best to cast it using GTK_CONTAINER (Tree), and pass it
+to the gtk_container_children() function. This creates a duplicate of
+the original list, so it's advisable to free it up using g_list_free()
+after you're done with it, or to iterate on it destructively, like
+this:
 
 <tscreen><verb>
-GtkWidget *gtk_list_new( void );
+    children = gtk_container_children (GTK_CONTAINER (tree));
+    while (children) {
+      do_something_nice (GTK_TREE_ITEM (children->data));
+      children = g_list_remove_link (children, children);
+}
 </verb></tscreen>
 
-Create a new GtkList object. The new widget is returned as a pointer
-to a GtkWidget object. NULL is returned on failure.
+The <tt>tree_owner</tt> field is defined only in subtrees, where it
+points to the GtkTreeItem widget which holds the tree in question.
+The <tt>level</tt> field indicates how deeply nested a particular tree
+is; root trees have level 0, and each successive level of subtrees has
+a level one greater than the parent level. This field is set only
+after a GtkTree widget is actually mapped (i.e. drawn on the screen).
 
+<sect2> Signals<label id="sec_GtkTree_Signals">
+<p>
 <tscreen><verb>
-void gtk_list_insert_items( GtkList *list,
-                            GList   *items,
-                            gint     position );
+void selection_changed( GtkTree *tree );
 </verb></tscreen>
 
-Insert list items into the list, starting at <tt/position/.
-<tt/items/ is a doubly linked list where each nodes data pointer is
-expected to point to a newly created GtkListItem.  The GList nodes of
-<tt/items/ are taken over by the list.
+This signal will be emitted whenever the <tt>selection</tt> field of a
+GtkTree has changed. This happens when a child of the GtkTree is
+selected or deselected.
 
 <tscreen><verb>
-void gtk_list_append_items( GtkList *list,
-                            GList   *items);
+void select_child( GtkTree   *tree,
+                   GtkWidget *child );
 </verb></tscreen>
 
-Insert list items just like gtk_list_insert_items() at the end of the
-list. The GList nodes of <tt/items/ are taken over by the list.
+This signal is emitted when a child of the GtkTree is about to get
+selected. This happens on calls to gtk_tree_select_item(),
+gtk_tree_select_child(), on <em>all</em> button presses and calls to
+gtk_tree_item_toggle() and gtk_item_toggle().  It may sometimes be
+indirectly triggered on other occasions where children get added to or
+removed from the GtkTree.
 
 <tscreen><verb>
-void gtk_list_prepend_items( GtkList *list,
-                             GList   *items);
+void unselect_child (GtkTree   *tree,
+                     GtkWidget *child);
 </verb></tscreen>
 
-Insert list items just like gtk_list_insert_items() at the very
-beginning of the list. The GList nodes of <tt/items/ are taken over by
-the list.
+This signal is emitted when a child of the GtkTree is about to get
+deselected. As of GTK+ 1.0.4, this seems to only occur on calls to
+gtk_tree_unselect_item() or gtk_tree_unselect_child(), and perhaps on
+other occasions, but <em>not</em> when a button press deselects a
+child, nor on emission of the "toggle" signal by gtk_item_toggle().
 
+<sect2> Functions and Macros<label id="sec_GtkTree_Functions">
+<p>
 <tscreen><verb>
-void gtk_list_remove_items( GtkList *list,
-                            GList   *items);
+guint gtk_tree_get_type( void );
 </verb></tscreen>
 
-Remove list items from the list. <tt/items/ is a doubly linked list
-where each nodes data pointer is expected to point to a direct child
-of list. It is the callers responsibility to make a call to
-g_list_free(items) afterwards. Also the caller has to destroy the list
-items himself.
+Returns the `GtkTree' type identifier.
 
 <tscreen><verb>
-void gtk_list_clear_items( GtkList *list,
-                           gint start,
-                           gint end );
+GtkWidget* gtk_tree_new( void );
 </verb></tscreen>
 
-Remove and destroy list items from the list. A widget is affected if
-its current position within the list is in the range specified by
-<tt/start/ and <tt/end/.
+Create a new GtkTree object. The new widget is returned as a pointer
+to a GtkWidget object. NULL is returned on failure.
 
 <tscreen><verb>
-void gtk_list_select_item( GtkList *list,
+void gtk_tree_append( GtkTree   *tree,
+                      GtkWidget *tree_item );
+</verb></tscreen>
+
+Append a tree item to a GtkTree.
+
+<tscreen><verb>
+void gtk_tree_prepend( GtkTree   *tree,
+                       GtkWidget *tree_item );
+</verb></tscreen>
+
+Prepend a tree item to a GtkTree.
+
+<tscreen><verb>
+void gtk_tree_insert( GtkTree   *tree,
+                      GtkWidget *tree_item,
+                      gint       position );
+</verb></tscreen>
+
+Insert a tree item into a GtkTree at the position in the list
+specified by <tt>position.</tt>
+
+<tscreen><verb>
+void gtk_tree_remove_items( GtkTree *tree,
+                            GList   *items );
+</verb></tscreen>
+
+Remove a list of items (in the form of a GList *) from a GtkTree.
+Note that removing an item from a tree dereferences (and thus usually)
+destroys it <em>and</em> its subtree, if it has one, <em>and</em> all
+subtrees in that subtree.  If you want to remove only one item, you
+can use gtk_container_remove().
+
+<tscreen><verb>
+void gtk_tree_clear_items( GtkTree *tree,
+                           gint     start,
+                           gint     end );
+</verb></tscreen>
+
+Remove the items from position <tt>start</tt> to position <tt>end</tt>
+from a GtkTree.  The same warning about dereferencing applies here, as
+gtk_tree_clear_items() simply constructs a list and passes it to
+gtk_tree_remove_items().
+
+<tscreen><verb>
+void gtk_tree_select_item( GtkTree *tree,
                            gint     item );
 </verb></tscreen>
 
-Invoke the select_child signal for a list item specified through its
-current position within the list.
+Emits the "select_item" signal for the child at position
+<tt>item</tt>, thus selecting the child (unless you unselect it in a
+signal handler).
 
 <tscreen><verb>
-void gtk_list_unselect_item( GtkList *list,
-                             gint     item);
+void gtk_tree_unselect_item( GtkTree *tree,
+                             gint     item );
 </verb></tscreen>
 
-Invoke the unselect_child signal for a list item specified through its
-current position within the list.
+Emits the "unselect_item" signal for the child at position
+<tt>item</tt>, thus unselecting the child.
 
 <tscreen><verb>
-void gtk_list_select_child( GtkList *list,
-                            GtkWidget *child);
+void gtk_tree_select_child( GtkTree   *tree,
+                            GtkWidget *tree_item );
 </verb></tscreen>
 
-Invoke the select_child signal for the specified child.
+Emits the "select_item" signal for the child <tt>tree_item</tt>, thus
+selecting it.
 
 <tscreen><verb>
-void gtk_list_unselect_child( GtkList   *list,
-                              GtkWidget *child);
+void gtk_tree_unselect_child( GtkTree   *tree,
+                              GtkWidget *tree_item );
 </verb></tscreen>
 
-Invoke the unselect_child signal for the specified child.
+Emits the "unselect_item" signal for the child <tt>tree_item</tt>,
+thus unselecting it.
 
 <tscreen><verb>
-gint gtk_list_child_position( GtkList *list,
-                              GtkWidget *child);
+gint gtk_tree_child_position( GtkTree   *tree,
+                              GtkWidget *child );
 </verb></tscreen>
 
-Return the position of <tt/child/ within the list. "-1" is returned on
-failure.
+Returns the position in the tree of <tt>child</tt>, unless
+<tt>child</tt> is not in the tree, in which case it returns -1.
 
 <tscreen><verb>
-void gtk_list_set_selection_mode( GtkList         *list,
-                                  GtkSelectionMode mode );
+void gtk_tree_set_selection_mode( GtkTree          *tree,
+                                  GtkSelectionMode  mode );
 </verb></tscreen>
 
-Set the selection mode MODE which can be of GTK_SELECTION_SINGLE,
-GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or
-GTK_SELECTION_EXTENDED.
+Sets the selection mode, which can be one of GTK_SELECTION_SINGLE (the
+default), GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE, or
+GTK_SELECTION_EXTENDED. This is only defined for root trees, which
+makes sense, since the root tree "owns" the selection. Setting it for
+subtrees has no effect at all; the value is simply ignored.
 
 <tscreen><verb>
-GtkList *GTK_LIST( gpointer obj );
+void gtk_tree_set_view_mode( GtkTree         *tree,
+                             GtkTreeViewMode  mode ); 
 </verb></tscreen>
 
-Cast a generic pointer to `GtkList *'. *Note Standard Macros::, for
-more info.
+Sets the "view mode", which can be either GTK_TREE_VIEW_LINE (the
+default) or GTK_TREE_VIEW_ITEM.  The view mode propagates from a tree
+to its subtrees, and can't be set exclusively to a subtree (this is
+not exactly true - see the example code comments).
+
+The term "view mode" is rather ambiguous - basically, it controls the
+way the highlight is drawn when one of a tree's children is selected.
+If it's GTK_TREE_VIEW_LINE, the entire GtkTreeItem widget is
+highlighted, while for GTK_TREE_VIEW_ITEM, only the child widget
+(i.e. usually the label) is highlighted.
 
 <tscreen><verb>
-GtkListClass *GTK_LIST_CLASS( gpointer class);
+void gtk_tree_set_view_lines( GtkTree *tree,
+                              guint    flag );
 </verb></tscreen>
 
-Cast a generic pointer to `GtkListClass*'. *Note Standard Macros::,
-for more info.
+Controls whether connecting lines between tree items are drawn.
+<tt>flag</tt> is either TRUE, in which case they are, or FALSE, in
+which case they aren't.
 
 <tscreen><verb>
-gint GTK_IS_LIST( gpointer obj);
+GtkTree *GTK_TREE (gpointer obj);
 </verb></tscreen>
 
-Determine if a generic pointer refers to a `GtkList' object. *Note
-Standard Macros::, for more info.
+Cast a generic pointer to `GtkTree *'.
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> Example
+<tscreen><verb>
+GtkTreeClass *GTK_TREE_CLASS (gpointer class);
+</verb></tscreen>
+
+Cast a generic pointer to `GtkTreeClass*'.
+
+<tscreen><verb>
+gint GTK_IS_TREE (gpointer obj);
+</verb></tscreen>
+
+Determine if a generic pointer refers to a `GtkTree' object.
+
+<tscreen><verb>
+gint GTK_IS_ROOT_TREE (gpointer obj)
+</verb></tscreen>
+
+Determine if a generic pointer refers to a `GtkTree' object
+<em>and</em> is a root tree. Though this will accept any pointer, the
+results of passing it a pointer that does not refer to a GtkTree are
+undefined and possibly harmful.
+
+<tscreen><verb>
+GtkTree *GTK_TREE_ROOT_TREE (gpointer obj)
+</verb></tscreen>
+
+Return the root tree of a pointer to a `GtkTree' object. The above
+warning applies.
+
+<tscreen><verb>
+GList *GTK_TREE_SELECTION( gpointer obj)
+</verb></tscreen>
+
+Return the selection list of the root tree of a `GtkTree' object. The
+above warning applies here, too.
+
+<sect1> Tree Item Widget<label id="sec_Tree_Item_Widget">
 <p>
-Following is an example program that will print out the changes of the
-selection of a GtkList, and lets you "arrest" list items into a prison
-by selecting them with the rightmost mouse button.
+The GtkTreeItem widget, like GtkListItem, is derived from GtkItem,
+which in turn is derived from GtkBin.  Therefore, the item itself is a
+generic container holding exactly one child widget, which can be of
+any type.  The GtkTreeItem widget has a number of extra fields, but
+the only one we need be concerned with is the <tt>subtree</tt> field.
+
+The definition for the GtkTreeItem struct looks like this:
 
 <tscreen><verb>
-/* example-start list list.c */
+struct _GtkTreeItem
+{
+  GtkItem item;
 
-/* Include the gtk+ header files
- * Include stdio.h, we need that for the printf() function
- */
-#include        <gtk/gtk.h>
-#include        <stdio.h>
+  GtkWidget *subtree;
+  GtkWidget *pixmaps_box;
+  GtkWidget *plus_pix_widget, *minus_pix_widget;
 
-/* This is our data identification string to store
- * data in list items
- */
-const gchar *list_item_data_key="list_item_data";
+  GList *pixmaps;              /* pixmap node for this items color depth */
 
+  guint expanded : 1;
+};
+</verb></tscreen>
 
-/* prototypes for signal handler that we are going to connect
- * to the GtkList widget
- */
-static void  sigh_print_selection( GtkWidget *gtklist,
-                                   gpointer   func_data);
+The <tt>pixmaps_box</tt> field is a GtkEventBox which catches clicks
+on the plus/minus symbol which controls expansion and collapsing.  The
+<tt>pixmaps</tt> field points to an internal data structure.  Since
+you can always obtain the subtree of a GtkTreeItem in a (relatively)
+type-safe manner with the GTK_TREE_ITEM_SUBTREE (Item) macro, it's
+probably advisable never to touch the insides of a GtkTreeItem unless
+you <em>really</em> know what you're doing.
 
-static void  sigh_button_event( GtkWidget      *gtklist,
-                                GdkEventButton *event,
-                                GtkWidget      *frame );
+Since it is directly derived from a GtkItem it can be treated as such
+by using the GTK_ITEM (TreeItem) macro. A GtkTreeItem usually holds a
+label, so the convenience function gtk_list_item_new_with_label() is
+provided. The same effect can be achieved using code like the
+following, which is actually copied verbatim from
+gtk_tree_item_new_with_label():
 
+<tscreen><verb>
+tree_item = gtk_tree_item_new ();
+label_widget = gtk_label_new (label);
+gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
 
-/* Main function to set up the user interface */
+gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
+gtk_widget_show (label_widget);
+</verb></tscreen>
 
-gint main (int    argc,
-           gchar *argv[])
-{                                  
-    GtkWidget *separator;
-    GtkWidget *window;
-    GtkWidget *vbox;
-    GtkWidget *scrolled_window;
-    GtkWidget *frame;
-    GtkWidget *gtklist;
-    GtkWidget *button;
-    GtkWidget *list_item;
-    GList *dlist;
-    guint i;
-    gchar buffer[64];
-    
-    
-    /* Initialize gtk+ (and subsequently gdk) */
-
-    gtk_init(&amp;argc, &amp;argv);
-    
-    
-    /* Create a window to put all the widgets in
-     * connect gtk_main_quit() to the "destroy" event of
-     * the window to handle window manager close-window-events
-     */
-    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
-    gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
-    gtk_signal_connect(GTK_OBJECT(window),
-                      "destroy",
-                      GTK_SIGNAL_FUNC(gtk_main_quit),
-                      NULL);
-    
-    
-    /* Inside the window we need a box to arrange the widgets
-     * vertically */
-    vbox=gtk_vbox_new(FALSE, 5);
-    gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
-    gtk_container_add(GTK_CONTAINER(window), vbox);
-    gtk_widget_show(vbox);
-    
-    /* This is the scrolled window to put the GtkList widget inside */
-    scrolled_window=gtk_scrolled_window_new(NULL, NULL);
-    gtk_widget_set_usize(scrolled_window, 250, 150);
-    gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
-    gtk_widget_show(scrolled_window);
-    
-    /* Create the GtkList widget.
-     * Connect the sigh_print_selection() signal handler
-     * function to the "selection_changed" signal of the GtkList
-     * to print out the selected items each time the selection
-     * has changed */
-    gtklist=gtk_list_new();
-    gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
-                                           gtklist);
-    gtk_widget_show(gtklist);
-    gtk_signal_connect(GTK_OBJECT(gtklist),
-                      "selection_changed",
-                      GTK_SIGNAL_FUNC(sigh_print_selection),
-                      NULL);
-    
-    /* We create a "Prison" to put a list item in ;) */
-    frame=gtk_frame_new("Prison");
-    gtk_widget_set_usize(frame, 200, 50);
-    gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
-    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
-    gtk_container_add(GTK_CONTAINER(vbox), frame);
-    gtk_widget_show(frame);
-    
-    /* Connect the sigh_button_event() signal handler to the GtkList
-     * which will handle the "arresting" of list items
-     */
-    gtk_signal_connect(GTK_OBJECT(gtklist),
-                      "button_release_event",
-                      GTK_SIGNAL_FUNC(sigh_button_event),
-                      frame);
-    
-    /* Create a separator */
-    separator=gtk_hseparator_new();
-    gtk_container_add(GTK_CONTAINER(vbox), separator);
-    gtk_widget_show(separator);
-    
-    /* Finally create a button and connect it's "clicked" signal
-     * to the destruction of the window */
-    button=gtk_button_new_with_label("Close");
-    gtk_container_add(GTK_CONTAINER(vbox), button);
-    gtk_widget_show(button);
-    gtk_signal_connect_object(GTK_OBJECT(button),
-                             "clicked",
-                             GTK_SIGNAL_FUNC(gtk_widget_destroy),
-                             GTK_OBJECT(window));
-    
-    
-    /* Now we create 5 list items, each having it's own
-     * label and add them to the GtkList using gtk_container_add()
-     * Also we query the text string from the label and
-     * associate it with the list_item_data_key for each list item
-     */
-    for (i=0; i<5; i++) {
-       GtkWidget       *label;
-       gchar           *string;
-       
-       sprintf(buffer, "ListItemContainer with Label #%d", i);
-       label=gtk_label_new(buffer);
-       list_item=gtk_list_item_new();
-       gtk_container_add(GTK_CONTAINER(list_item), label);
-       gtk_widget_show(label);
-       gtk_container_add(GTK_CONTAINER(gtklist), list_item);
-       gtk_widget_show(list_item);
-       gtk_label_get(GTK_LABEL(label), &amp;string);
-       gtk_object_set_data(GTK_OBJECT(list_item),
-                           list_item_data_key,
-                           string);
-    }
-    /* Here, we are creating another 5 labels, this time
-     * we use gtk_list_item_new_with_label() for the creation
-     * we can't query the text string from the label because
-     * we don't have the labels pointer and therefore
-     * we just associate the list_item_data_key of each
-     * list item with the same text string.
-     * For adding of the list items we put them all into a doubly
-     * linked list (GList), and then add them by a single call to
-     * gtk_list_append_items().
-     * Because we use g_list_prepend() to put the items into the
-     * doubly linked list, their order will be descending (instead
-     * of ascending when using g_list_append())
-     */
-    dlist=NULL;
-    for (; i<10; i++) {
-       sprintf(buffer, "List Item with Label %d", i);
-       list_item=gtk_list_item_new_with_label(buffer);
-       dlist=g_list_prepend(dlist, list_item);
-       gtk_widget_show(list_item);
-       gtk_object_set_data(GTK_OBJECT(list_item),
-                           list_item_data_key,
-                           "ListItem with integrated Label");
-    }
-    gtk_list_append_items(GTK_LIST(gtklist), dlist);
-    
-    /* Finally we want to see the window, don't we? ;) */
-    gtk_widget_show(window);
-    
-    /* Fire up the main event loop of gtk */
-    gtk_main();
-    
-    /* We get here after gtk_main_quit() has been called which
-     * happens if the main window gets destroyed
-     */
-    return(0);
-}
-
-/* This is the signal handler that got connected to button
- * press/release events of the GtkList
- */
-void sigh_button_event( GtkWidget      *gtklist,
-                        GdkEventButton *event,
-                        GtkWidget      *frame )
-{
-    /* We only do something if the third (rightmost mouse button
-     * was released
-     */
-    if (event->type==GDK_BUTTON_RELEASE &amp;&amp;
-       event->button==3) {
-       GList           *dlist, *free_list;
-       GtkWidget       *new_prisoner;
-       
-       /* Fetch the currently selected list item which
-        * will be our next prisoner ;)
-        */
-       dlist=GTK_LIST(gtklist)->selection;
-       if (dlist)
-               new_prisoner=GTK_WIDGET(dlist->data);
-       else
-               new_prisoner=NULL;
-       
-       /* Look for already imprisoned list items, we
-        * will put them back into the list.
-        * Remember to free the doubly linked list that
-        * gtk_container_children() returns
-        */
-       dlist=gtk_container_children(GTK_CONTAINER(frame));
-       free_list=dlist;
-       while (dlist) {
-           GtkWidget       *list_item;
-           
-           list_item=dlist->data;
-           
-           gtk_widget_reparent(list_item, gtklist);
-           
-           dlist=dlist->next;
-       }
-       g_list_free(free_list);
-       
-       /* If we have a new prisoner, remove him from the
-        * GtkList and put him into the frame "Prison".
-        * We need to unselect the item first.
-        */
-       if (new_prisoner) {
-           GList   static_dlist;
-           
-           static_dlist.data=new_prisoner;
-           static_dlist.next=NULL;
-           static_dlist.prev=NULL;
-           
-           gtk_list_unselect_child(GTK_LIST(gtklist),
-                                   new_prisoner);
-           gtk_widget_reparent(new_prisoner, frame);
-       }
-    }
-}
-
-/* This is the signal handler that gets called if GtkList
- * emits the "selection_changed" signal
- */
-void sigh_print_selection( GtkWidget *gtklist,
-                           gpointer   func_data)
-{
-    GList   *dlist;
-    
-    /* Fetch the doubly linked list of selected items
-     * of the GtkList, remember to treat this as read-only!
-     */
-    dlist=GTK_LIST(gtklist)->selection;
-    
-    /* If there are no selected items there is nothing more
-     * to do than just telling the user so
-     */
-    if (!dlist) {
-       g_print("Selection cleared\n");
-       return;
-    }
-    /* Ok, we got a selection and so we print it
-     */
-    g_print("The selection is a ");
-    
-    /* Get the list item from the doubly linked list
-     * and then query the data associated with list_item_data_key.
-     * We then just print it */
-    while (dlist) {
-       GtkObject       *list_item;
-       gchar           *item_data_string;
-       
-       list_item=GTK_OBJECT(dlist->data);
-       item_data_string=gtk_object_get_data(list_item,
-                                            list_item_data_key);
-       g_print("%s ", item_data_string);
-       
-       dlist=dlist->next;
-    }
-    g_print("\n");
-}
-/* example-end */
-</verb></tscreen>
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> List Item Widget
-<p>
-The GtkListItem widget is designed to act as a container holding up to
-one child, providing functions for selection/deselection just like the
-GtkList widget requires them for its children.
-
-A GtkListItem has its own window to receive events and has its own
-background color which is usually white.
-
-As it is directly derived from a GtkItem it can be treated as such by
-using the GTK_ITEM(ListItem) macro, see the GtkItem widget for more on
-this. Usually a GtkListItem just holds a label to identify e.g. a
-filename within a GtkList -- therefore the convenience function
-gtk_list_item_new_with_label() is provided. The same effect can be
-achieved by creating a GtkLabel on its own, setting its alignment to
-xalign=0 and yalign=0.5 with a subsequent container addition to the
-GtkListItem.
-
-As one is not forced to add a GtkLabel to a GtkListItem, you could
-also add a GtkVBox or a GtkArrow etc. to the GtkListItem.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Signals
-<p>
-A GtkListItem does not create new signals on its own, but inherits
-the signals of a GtkItem. *Note GtkItem::, for more info.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Functions
-<p>
-<tscreen><verb>
-guint gtk_list_item_get_type( void );
-</verb></tscreen>
-
-Returns the `GtkListItem' type identifier.
-
-<tscreen><verb>
-GtkWidget *gtk_list_item_new( void );
-</verb></tscreen>
-
-Create a new GtkListItem object. The new widget is returned as a
-pointer to a GtkWidget object. NULL is returned on failure.
-
-<tscreen><verb>
-GtkWidget *gtk_list_item_new_with_label( gchar *label );
-</verb></tscreen>
-
-Create a new GtkListItem object, having a single GtkLabel as the sole
-child. The new widget is returned as a pointer to a GtkWidget
-object. NULL is returned on failure.
-
-<tscreen><verb>
-void gtk_list_item_select( GtkListItem *list_item );
-</verb></tscreen>
-
-This function is basically a wrapper around a call to gtk_item_select
-(GTK_ITEM (list_item)) which will emit the select signal.  *Note
-GtkItem::, for more info.
-
-<tscreen><verb>
-void gtk_list_item_deselect( GtkListItem *list_item );
-</verb></tscreen>
-
-This function is basically a wrapper around a call to
-gtk_item_deselect (GTK_ITEM (list_item)) which will emit the deselect
-signal.  *Note GtkItem::, for more info.
-
-<tscreen><verb>
-GtkListItem *GTK_LIST_ITEM( gpointer obj );
-</verb></tscreen>
-
-Cast a generic pointer to `GtkListItem*'. *Note Standard Macros::, for
-more info.
-
-<tscreen><verb>
-GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class );
-</verb></tscreen>
-
-Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::,
-for more info.
-
-<tscreen><verb>
-gint GTK_IS_LIST_ITEM( gpointer obj );
-</verb></tscreen>
-
-Determine if a generic pointer refers to a `GtkListItem' object.
-*Note Standard Macros::, for more info.
-<!-- ----------------------------------------------------------------- -->
-<sect1> Example
-<p>
-Please see the GtkList example on this, which covers the usage of a
-GtkListItem as well.
-
-<!-- ***************************************************************** -->
-<sect> Tree Widget<label id="sec_Tree_Widgets">
-<!-- ***************************************************************** -->
-<p>
-The purpose of tree widgets is to display hierarchically-organized
-data. The GtkTree widget itself is a vertical container for widgets of
-type GtkTreeItem. GtkTree itself is not terribly different from
-GtkList - both are derived directly from GtkContainer, and the
-GtkContainer methods work in the same way on GtkTree widgets as on
-GtkList widgets. The difference is that GtkTree widgets can be nested
-within other GtkTree widgets. We'll see how to do this shortly.
-
-The GtkTree widget has its own window, and defaults to a white
-background, as does GtkList. Also, most of the GtkTree methods work in
-the same way as the corresponding GtkList ones. However, GtkTree is
-not derived from GtkList, so you cannot use them interchangeably.
-
-<sect1> Creating a Tree
-<p>
-A GtkTree is created in the usual way, using:
-
-<tscreen><verb>
-GtkWidget* gtk_tree_new( void );
-</verb></tscreen>
-
-Like the GtkList widget, a GtkTree will simply keep growing as more
-items are added to it, as well as when subtrees are expanded.  For
-this reason, they are almost always packed into a
-GtkScrolledWindow. You might want to use gtk_widget_set_usize() on the
-scrolled window to ensure that it is big enough to see the tree's
-items, as the default size for GtkScrolledWindow is quite small.
-
-Now that you have a tree, you'll probably want to add some items to
-it.  <ref id="sec_Tree_Item_Widget" name="The Tree Item Widget"> below
-explains the gory details of GtkTreeItem. For now, it'll suffice to
-create one, using:
-
-<tscreen><verb>
-GtkWidget* gtk_tree_item_new_with_label( gchar *label );
-</verb></tscreen>
-
-You can then add it to the tree using one of the following (see
-<ref id="sec_GtkTree_Functions" name="Functions and Macros">
-below for more options):
-
-<tscreen><verb>
-void gtk_tree_append( GtkTree    *tree,
-                       GtkWidget *tree_item );
-
-void gtk_tree_prepend( GtkTree   *tree,
-                       GtkWidget *tree_item );
-</verb></tscreen>
-
-Note that you must add items to a GtkTree one at a time - there is no
-equivalent to gtk_list_*_items().
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Adding a Subtree
-<p>
-A subtree is created like any other GtkTree widget. A subtree is added
-to another tree beneath a tree item, using:
-
-<tscreen><verb>
-void gtk_tree_item_set_subtree( GtkTreeItem *tree_item,
-                                GtkWidget   *subtree );
-</verb></tscreen>
-
-You do not need to call gtk_widget_show() on a subtree before or after
-adding it to a GtkTreeItem. However, you <em>must</em> have added the
-GtkTreeItem in question to a parent tree before calling
-gtk_tree_item_set_subtree(). This is because, technically, the parent
-of the subtree is <em>not</em> the GtkTreeItem which "owns" it, but
-rather the GtkTree which holds that GtkTreeItem.
-
-When you add a subtree to a GtkTreeItem, a plus or minus sign appears
-beside it, which the user can click on to "expand" or "collapse" it,
-meaning, to show or hide its subtree. GtkTreeItems are collapsed by
-default. Note that when you collapse a GtkTreeItem, any selected
-items in its subtree remain selected, which may not be what the user
-expects.
-
-<!-- ----------------------------------------------------------------- -->
-<sect1> Handling the Selection List
-<p>
-As with GtkList, the GtkTree type has a <tt>selection</tt> field, and
-it is possible to control the behaviour of the tree (somewhat) by
-setting the selection type using:
-
-<tscreen><verb>
-void gtk_tree_set_selection_mode( GtkTree          *tree,
-                                  GtkSelectionMode  mode );
-</verb></tscreen>
-
-The semantics associated with the various selection modes are
-described in the section on the GtkList widget. As with the GtkList
-widget, the "select_child", "unselect_child" (not really - see <ref
-id="sec_GtkTree_Signals" name="Signals"> below for an explanation),
-and "selection_changed" signals are emitted when list items are
-selected or unselected. However, in order to take advantage of these
-signals, you need to know <em>which</em> GtkTree widget they will be
-emitted by, and where to find the list of selected items.
-
-This is a source of potential confusion. The best way to explain this
-is that though all GtkTree widgets are created equal, some are more
-equal than others. All GtkTree widgets have their own X window, and
-can therefore receive events such as mouse clicks (if their
-GtkTreeItems or their children don't catch them first!). However, to
-make GTK_SELECTION_SINGLE and GTK_SELECTION_BROWSE selection types
-behave in a sane manner, the list of selected items is specific to the
-topmost GtkTree widget in a hierarchy, known as the "root tree".
-
-Thus, accessing the <tt>selection</tt>field directly in an arbitrary
-GtkTree widget is not a good idea unless you <em>know</em> it's the
-root tree.  Instead, use the GTK_TREE_SELECTION (Tree) macro, which
-gives the root tree's selection list as a GList pointer. Of course,
-this list can include items that are not in the subtree in question if 
-the selection type is GTK_SELECTION_MULTIPLE.
-
-Finally, the "select_child" (and "unselect_child", in theory) signals
-are emitted by all trees, but the "selection_changed" signal is only
-emitted by the root tree. Consequently, if you want to handle the
-"select_child" signal for a tree and all its subtrees, you will have
-to call gtk_signal_connect() for every subtree.
-
-<sect1> Tree Widget Internals
-<p>
-The GtkTree's struct definition looks like this:
-
-<tscreen><verb>
-struct _GtkTree
-{
-  GtkContainer container;
-
-  GList *children;
-  
-  GtkTree* root_tree; /* owner of selection list */
-  GtkWidget* tree_owner;
-  GList *selection;
-  guint level;
-  guint indent_value;
-  guint current_indent;
-  guint selection_mode : 2;
-  guint view_mode : 1;
-  guint view_line : 1;
-};
-</verb></tscreen>
-
-The perils associated with accessing the <tt>selection</tt> field
-directly have already been mentioned. The other important fields of
-the struct can also be accessed with handy macros or class functions.
-GTK_TREE_IS_ROOT_TREE (Tree) returns a boolean value which indicates
-whether a tree is the root tree in a GtkTree hierarchy, while
-GTK_TREE_ROOT_TREE (Tree) returns the root tree, an object of type
-GtkTree (so, remember to cast it using GTK_WIDGET (Tree) if you want
-to use one of the gtk_widget_*() functions on it).
-
-Instead of directly accessing the children field of a GtkTree widget,
-it's probably best to cast it using GTK_CONTAINER (Tree), and pass it
-to the gtk_container_children() function. This creates a duplicate of
-the original list, so it's advisable to free it up using g_list_free()
-after you're done with it, or to iterate on it destructively, like
-this:
-
-<tscreen><verb>
-    children = gtk_container_children (GTK_CONTAINER (tree));
-    while (children) {
-      do_something_nice (GTK_TREE_ITEM (children->data));
-      children = g_list_remove_link (children, children);
-}
-</verb></tscreen>
-
-The <tt>tree_owner</tt> field is defined only in subtrees, where it
-points to the GtkTreeItem widget which holds the tree in question.
-The <tt>level</tt> field indicates how deeply nested a particular tree
-is; root trees have level 0, and each successive level of subtrees has
-a level one greater than the parent level. This field is set only
-after a GtkTree widget is actually mapped (i.e. drawn on the screen).
-
-<sect2> Signals<label id="sec_GtkTree_Signals">
-<p>
-<tscreen><verb>
-void selection_changed( GtkTree *tree );
-</verb></tscreen>
-
-This signal will be emitted whenever the <tt>selection</tt> field of a
-GtkTree has changed. This happens when a child of the GtkTree is
-selected or deselected.
-
-<tscreen><verb>
-void select_child( GtkTree   *tree,
-                   GtkWidget *child );
-</verb></tscreen>
-
-This signal is emitted when a child of the GtkTree is about to get
-selected. This happens on calls to gtk_tree_select_item(),
-gtk_tree_select_child(), on <em>all</em> button presses and calls to
-gtk_tree_item_toggle() and gtk_item_toggle().  It may sometimes be
-indirectly triggered on other occasions where children get added to or
-removed from the GtkTree.
-
-<tscreen><verb>
-void unselect_child (GtkTree   *tree,
-                     GtkWidget *child);
-</verb></tscreen>
-
-This signal is emitted when a child of the GtkTree is about to get
-deselected. As of GTK+ 1.0.4, this seems to only occur on calls to
-gtk_tree_unselect_item() or gtk_tree_unselect_child(), and perhaps on
-other occasions, but <em>not</em> when a button press deselects a
-child, nor on emission of the "toggle" signal by gtk_item_toggle().
-
-<sect2> Functions and Macros<label id="sec_GtkTree_Functions">
-<p>
-<tscreen><verb>
-guint gtk_tree_get_type( void );
-</verb></tscreen>
-
-Returns the `GtkTree' type identifier.
-
-<tscreen><verb>
-GtkWidget* gtk_tree_new( void );
-</verb></tscreen>
-
-Create a new GtkTree object. The new widget is returned as a pointer
-to a GtkWidget object. NULL is returned on failure.
-
-<tscreen><verb>
-void gtk_tree_append( GtkTree   *tree,
-                      GtkWidget *tree_item );
-</verb></tscreen>
-
-Append a tree item to a GtkTree.
-
-<tscreen><verb>
-void gtk_tree_prepend( GtkTree   *tree,
-                       GtkWidget *tree_item );
-</verb></tscreen>
-
-Prepend a tree item to a GtkTree.
-
-<tscreen><verb>
-void gtk_tree_insert( GtkTree   *tree,
-                      GtkWidget *tree_item,
-                      gint       position );
-</verb></tscreen>
-
-Insert a tree item into a GtkTree at the position in the list
-specified by <tt>position.</tt>
-
-<tscreen><verb>
-void gtk_tree_remove_items( GtkTree *tree,
-                            GList   *items );
-</verb></tscreen>
-
-Remove a list of items (in the form of a GList *) from a GtkTree.
-Note that removing an item from a tree dereferences (and thus usually)
-destroys it <em>and</em> its subtree, if it has one, <em>and</em> all
-subtrees in that subtree.  If you want to remove only one item, you
-can use gtk_container_remove().
-
-<tscreen><verb>
-void gtk_tree_clear_items( GtkTree *tree,
-                           gint     start,
-                           gint     end );
-</verb></tscreen>
-
-Remove the items from position <tt>start</tt> to position <tt>end</tt>
-from a GtkTree.  The same warning about dereferencing applies here, as
-gtk_tree_clear_items() simply constructs a list and passes it to
-gtk_tree_remove_items().
-
-<tscreen><verb>
-void gtk_tree_select_item( GtkTree *tree,
-                           gint     item );
-</verb></tscreen>
-
-Emits the "select_item" signal for the child at position
-<tt>item</tt>, thus selecting the child (unless you unselect it in a
-signal handler).
-
-<tscreen><verb>
-void gtk_tree_unselect_item( GtkTree *tree,
-                             gint     item );
-</verb></tscreen>
-
-Emits the "unselect_item" signal for the child at position
-<tt>item</tt>, thus unselecting the child.
-
-<tscreen><verb>
-void gtk_tree_select_child( GtkTree   *tree,
-                            GtkWidget *tree_item );
-</verb></tscreen>
-
-Emits the "select_item" signal for the child <tt>tree_item</tt>, thus
-selecting it.
-
-<tscreen><verb>
-void gtk_tree_unselect_child( GtkTree   *tree,
-                              GtkWidget *tree_item );
-</verb></tscreen>
-
-Emits the "unselect_item" signal for the child <tt>tree_item</tt>,
-thus unselecting it.
-
-<tscreen><verb>
-gint gtk_tree_child_position( GtkTree   *tree,
-                              GtkWidget *child );
-</verb></tscreen>
-
-Returns the position in the tree of <tt>child</tt>, unless
-<tt>child</tt> is not in the tree, in which case it returns -1.
-
-<tscreen><verb>
-void gtk_tree_set_selection_mode( GtkTree          *tree,
-                                  GtkSelectionMode  mode );
-</verb></tscreen>
-
-Sets the selection mode, which can be one of GTK_SELECTION_SINGLE (the
-default), GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE, or
-GTK_SELECTION_EXTENDED. This is only defined for root trees, which
-makes sense, since the root tree "owns" the selection. Setting it for
-subtrees has no effect at all; the value is simply ignored.
-
-<tscreen><verb>
-void gtk_tree_set_view_mode( GtkTree         *tree,
-                             GtkTreeViewMode  mode ); 
-</verb></tscreen>
-
-Sets the "view mode", which can be either GTK_TREE_VIEW_LINE (the
-default) or GTK_TREE_VIEW_ITEM.  The view mode propagates from a tree
-to its subtrees, and can't be set exclusively to a subtree (this is
-not exactly true - see the example code comments).
-
-The term "view mode" is rather ambiguous - basically, it controls the
-way the highlight is drawn when one of a tree's children is selected.
-If it's GTK_TREE_VIEW_LINE, the entire GtkTreeItem widget is
-highlighted, while for GTK_TREE_VIEW_ITEM, only the child widget
-(i.e. usually the label) is highlighted.
-
-<tscreen><verb>
-void gtk_tree_set_view_lines( GtkTree *tree,
-                              guint    flag );
-</verb></tscreen>
-
-Controls whether connecting lines between tree items are drawn.
-<tt>flag</tt> is either TRUE, in which case they are, or FALSE, in
-which case they aren't.
-
-<tscreen><verb>
-GtkTree *GTK_TREE (gpointer obj);
-</verb></tscreen>
-
-Cast a generic pointer to `GtkTree *'.
-
-<tscreen><verb>
-GtkTreeClass *GTK_TREE_CLASS (gpointer class);
-</verb></tscreen>
-
-Cast a generic pointer to `GtkTreeClass*'.
-
-<tscreen><verb>
-gint GTK_IS_TREE (gpointer obj);
-</verb></tscreen>
-
-Determine if a generic pointer refers to a `GtkTree' object.
-
-<tscreen><verb>
-gint GTK_IS_ROOT_TREE (gpointer obj)
-</verb></tscreen>
-
-Determine if a generic pointer refers to a `GtkTree' object
-<em>and</em> is a root tree. Though this will accept any pointer, the
-results of passing it a pointer that does not refer to a GtkTree are
-undefined and possibly harmful.
-
-<tscreen><verb>
-GtkTree *GTK_TREE_ROOT_TREE (gpointer obj)
-</verb></tscreen>
-
-Return the root tree of a pointer to a `GtkTree' object. The above
-warning applies.
-
-<tscreen><verb>
-GList *GTK_TREE_SELECTION( gpointer obj)
-</verb></tscreen>
-
-Return the selection list of the root tree of a `GtkTree' object. The
-above warning applies here, too.
-
-<sect1> Tree Item Widget<label id="sec_Tree_Item_Widget">
-<p>
-The GtkTreeItem widget, like GtkListItem, is derived from GtkItem,
-which in turn is derived from GtkBin.  Therefore, the item itself is a
-generic container holding exactly one child widget, which can be of
-any type.  The GtkTreeItem widget has a number of extra fields, but
-the only one we need be concerned with is the <tt>subtree</tt> field.
-
-The definition for the GtkTreeItem struct looks like this:
-
-<tscreen><verb>
-struct _GtkTreeItem
-{
-  GtkItem item;
-
-  GtkWidget *subtree;
-  GtkWidget *pixmaps_box;
-  GtkWidget *plus_pix_widget, *minus_pix_widget;
-
-  GList *pixmaps;              /* pixmap node for this items color depth */
-
-  guint expanded : 1;
-};
-</verb></tscreen>
-
-The <tt>pixmaps_box</tt> field is a GtkEventBox which catches clicks
-on the plus/minus symbol which controls expansion and collapsing.  The
-<tt>pixmaps</tt> field points to an internal data structure.  Since
-you can always obtain the subtree of a GtkTreeItem in a (relatively)
-type-safe manner with the GTK_TREE_ITEM_SUBTREE (Item) macro, it's
-probably advisable never to touch the insides of a GtkTreeItem unless
-you <em>really</em> know what you're doing.
-
-Since it is directly derived from a GtkItem it can be treated as such
-by using the GTK_ITEM (TreeItem) macro. A GtkTreeItem usually holds a
-label, so the convenience function gtk_list_item_new_with_label() is
-provided. The same effect can be achieved using code like the
-following, which is actually copied verbatim from
-gtk_tree_item_new_with_label():
-
-<tscreen><verb>
-tree_item = gtk_tree_item_new ();
-label_widget = gtk_label_new (label);
-gtk_misc_set_alignment (GTK_MISC (label_widget), 0.0, 0.5);
-
-gtk_container_add (GTK_CONTAINER (tree_item), label_widget);
-gtk_widget_show (label_widget);
-</verb></tscreen>
-
-As one is not forced to add a GtkLabel to a GtkTreeItem, you could
-also add a GtkHBox or a GtkArrow, or even a GtkNotebook (though your
-app will likely be quite unpopular in this case) to the GtkTreeItem.
+As one is not forced to add a GtkLabel to a GtkTreeItem, you could
+also add a GtkHBox or a GtkArrow, or even a GtkNotebook (though your
+app will likely be quite unpopular in this case) to the GtkTreeItem.
 
 If you remove all the items from a subtree, it will be destroyed and
 unparented, unless you reference it beforehand, and the GtkTreeItem
@@ -9139,12 +8748,6 @@ from your time.
 <sect1> Drawing Area
 <p>
 <!-- ----------------------------------------------------------------- -->
-<sect1> Fixed Container
-<p>
-<!-- ----------------------------------------------------------------- -->
-<sect1> Frame
-<p>
-<!-- ----------------------------------------------------------------- -->
 <sect1> Font Selection Dialog
 <p>
 <!-- ----------------------------------------------------------------- -->
@@ -14188,283 +13791,574 @@ The other event type that is different from the others is
 data types, which allows it to be cast to a specific
 event data type within a signal handler.
 
-<!-- Just a big list for now, needs expanding upon - TRG -->
-So, the event data types are defined as follows:
+<!-- Just a big list for now, needs expanding upon - TRG -->
+So, the event data types are defined as follows:
+
+<tscreen><verb>
+struct _GdkEventAny
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+};
+
+struct _GdkEventExpose
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkRectangle area;
+  gint count; /* If non-zero, how many more events follow. */
+};
+
+struct _GdkEventNoExpose
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  /* XXX: does anyone need the X major_code or minor_code fields? */
+};
+
+struct _GdkEventVisibility
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkVisibilityState state;
+};
+
+struct _GdkEventMotion
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+  guint state;
+  gint16 is_hint;
+  GdkInputSource source;
+  guint32 deviceid;
+  gdouble x_root, y_root;
+};
+
+struct _GdkEventButton
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  gdouble x;
+  gdouble y;
+  gdouble pressure;
+  gdouble xtilt;
+  gdouble ytilt;
+  guint state;
+  guint button;
+  GdkInputSource source;
+  guint32 deviceid;
+  gdouble x_root, y_root;
+};
+
+struct _GdkEventKey
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  guint state;
+  guint keyval;
+  gint length;
+  gchar *string;
+};
+
+struct _GdkEventCrossing
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkWindow *subwindow;
+  GdkNotifyType detail;
+};
+
+struct _GdkEventFocus
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  gint16 in;
+};
+
+struct _GdkEventConfigure
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  gint16 x, y;
+  gint16 width;
+  gint16 height;
+};
+
+struct _GdkEventProperty
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkAtom atom;
+  guint32 time;
+  guint state;
+};
+
+struct _GdkEventSelection
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  GdkAtom selection;
+  GdkAtom target;
+  GdkAtom property;
+  guint32 requestor;
+  guint32 time;
+};
+
+/* This event type will be used pretty rarely. It only is important
+   for XInput aware programs that are drawing their own cursor */
+
+struct _GdkEventProximity
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 time;
+  GdkInputSource source;
+  guint32 deviceid;
+};
+
+struct _GdkEventDragRequest
+{
+  GdkEventType type;
+  GdkWindow *window;
+  gint8 send_event;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint sendreply:1;
+      guint willaccept:1;
+      guint delete_data:1; /* Do *not* delete if link is sent, only
+                              if data is sent */
+      guint senddata:1;
+      guint reserved:22;
+    } flags;
+    glong allflags;
+  } u;
+  guint8 isdrop; /* This gdk event can be generated by a couple of
+                    X events - this lets the app know whether the
+                    drop really occurred or we just set the data */
+
+  GdkPoint drop_coords;
+  gchar *data_type;
+  guint32 timestamp;
+};
 
-<tscreen><verb>
-struct _GdkEventAny
+struct _GdkEventDragBegin
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint reserved:28;
+    } flags;
+    glong allflags;
+  } u;
 };
 
-struct _GdkEventExpose
+struct _GdkEventDropEnter
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  GdkRectangle area;
-  gint count; /* If non-zero, how many more events follow. */
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint sendreply:1;
+      guint extended_typelist:1;
+      guint reserved:26;
+    } flags;
+    glong allflags;
+  } u;
 };
 
-struct _GdkEventNoExpose
+struct _GdkEventDropLeave
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  /* XXX: does anyone need the X major_code or minor_code fields? */
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint reserved:28;
+    } flags;
+    glong allflags;
+  } u;
 };
 
-struct _GdkEventVisibility
+struct _GdkEventDropDataAvailable
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  GdkVisibilityState state;
+  guint32 requestor;
+  union {
+    struct {
+      guint protocol_version:4;
+      guint isdrop:1;
+      guint reserved:25;
+    } flags;
+    glong allflags;
+  } u;
+  gchar *data_type; /* MIME type */
+  gulong data_numbytes;
+  gpointer data;
+  guint32 timestamp;
+  GdkPoint coords;
 };
 
-struct _GdkEventMotion
+struct _GdkEventClient
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  guint32 time;
-  gdouble x;
-  gdouble y;
-  gdouble pressure;
-  gdouble xtilt;
-  gdouble ytilt;
-  guint state;
-  gint16 is_hint;
-  GdkInputSource source;
-  guint32 deviceid;
-  gdouble x_root, y_root;
+  GdkAtom message_type;
+  gushort data_format;
+  union {
+    char b[20];
+    short s[10];
+    long l[5];
+  } data;
 };
 
-struct _GdkEventButton
+struct _GdkEventOther
 {
   GdkEventType type;
   GdkWindow *window;
   gint8 send_event;
-  guint32 time;
-  gdouble x;
-  gdouble y;
-  gdouble pressure;
-  gdouble xtilt;
-  gdouble ytilt;
-  guint state;
-  guint button;
-  GdkInputSource source;
-  guint32 deviceid;
-  gdouble x_root, y_root;
+  GdkXEvent *xevent;
+};
+</verb></tscreen>
+
+<!-- ***************************************************************** -->
+<sect> Code Examples
+<!-- ***************************************************************** -->
+<p>
+Below are the code examples that are used in the above text
+which are not included in complete form elsewhere.
+
+<!-- ----------------------------------------------------------------- -->
+<sect1>Tictactoe
+<!-- ----------------------------------------------------------------- -->
+<sect2>tictactoe.h
+<p>
+<tscreen><verb>
+/* example-start tictactoe tictactoe.h */
+
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __TICTACTOE_H__
+#define __TICTACTOE_H__
+
+
+#include <gdk/gdk.h>
+#include <gtk/gtkvbox.h>
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+#define TICTACTOE(obj)          GTK_CHECK_CAST (obj, tictactoe_get_type (), Tictactoe)
+#define TICTACTOE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, tictactoe_get_type (), TictactoeClass)
+#define IS_TICTACTOE(obj)       GTK_CHECK_TYPE (obj, tictactoe_get_type ())
+
+
+typedef struct _Tictactoe       Tictactoe;
+typedef struct _TictactoeClass  TictactoeClass;
+
+struct _Tictactoe
+{
+  GtkVBox vbox;
+  
+  GtkWidget *buttons[3][3];
+};
+
+struct _TictactoeClass
+{
+  GtkVBoxClass parent_class;
+
+  void (* tictactoe) (Tictactoe *ttt);
+};
+
+guint          tictactoe_get_type        (void);
+GtkWidget*     tictactoe_new             (void);
+void          tictactoe_clear           (Tictactoe *ttt);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* __TICTACTOE_H__ */
+
+/* example-end */
+</verb></tscreen>
+
+<!-- ----------------------------------------------------------------- -->
+<sect2>tictactoe.c
+<p>
+<tscreen><verb>
+/* example-start tictactoe tictactoe.c */
+
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include "gtk/gtksignal.h"
+#include "gtk/gtktable.h"
+#include "gtk/gtktogglebutton.h"
+#include "tictactoe.h"
+
+enum {
+  TICTACTOE_SIGNAL,
+  LAST_SIGNAL
 };
 
-struct _GdkEventKey
+static void tictactoe_class_init          (TictactoeClass *klass);
+static void tictactoe_init                (Tictactoe      *ttt);
+static void tictactoe_toggle              (GtkWidget *widget, Tictactoe *ttt);
+
+static gint tictactoe_signals[LAST_SIGNAL] = { 0 };
+
+guint
+tictactoe_get_type ()
+{
+  static guint ttt_type = 0;
+
+  if (!ttt_type)
+    {
+      GtkTypeInfo ttt_info =
+      {
+       "Tictactoe",
+       sizeof (Tictactoe),
+       sizeof (TictactoeClass),
+       (GtkClassInitFunc) tictactoe_class_init,
+       (GtkObjectInitFunc) tictactoe_init,
+        (GtkArgSetFunc) NULL,
+        (GtkArgGetFunc) NULL
+      };
+
+      ttt_type = gtk_type_unique (gtk_vbox_get_type (), &amp;ttt_info);
+    }
+
+  return ttt_type;
+}
+
+static void
+tictactoe_class_init (TictactoeClass *class)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 time;
-  guint state;
-  guint keyval;
-  gint length;
-  gchar *string;
-};
+  GtkObjectClass *object_class;
 
-struct _GdkEventCrossing
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkWindow *subwindow;
-  GdkNotifyType detail;
-};
+  object_class = (GtkObjectClass*) class;
+  
+  tictactoe_signals[TICTACTOE_SIGNAL] = gtk_signal_new ("tictactoe",
+                                        GTK_RUN_FIRST,
+                                        object_class->type,
+                                        GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
+                                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
 
-struct _GdkEventFocus
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  gint16 in;
-};
 
-struct _GdkEventConfigure
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  gint16 x, y;
-  gint16 width;
-  gint16 height;
-};
+  gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
 
-struct _GdkEventProperty
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkAtom atom;
-  guint32 time;
-  guint state;
-};
+  class->tictactoe = NULL;
+}
 
-struct _GdkEventSelection
+static void
+tictactoe_init (Tictactoe *ttt)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkAtom selection;
-  GdkAtom target;
-  GdkAtom property;
-  guint32 requestor;
-  guint32 time;
-};
+  GtkWidget *table;
+  gint i,j;
+  
+  table = gtk_table_new (3, 3, TRUE);
+  gtk_container_add (GTK_CONTAINER(ttt), table);
+  gtk_widget_show (table);
 
-/* This event type will be used pretty rarely. It only is important
-   for XInput aware programs that are drawing their own cursor */
+  for (i=0;i<3; i++)
+    for (j=0;j<3; j++)
+      {
+       ttt->buttons[i][j] = gtk_toggle_button_new ();
+       gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j], 
+                                  i, i+1, j, j+1);
+       gtk_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
+                           GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
+       gtk_widget_set_usize (ttt->buttons[i][j], 20, 20);
+       gtk_widget_show (ttt->buttons[i][j]);
+      }
+}
 
-struct _GdkEventProximity
+GtkWidget*
+tictactoe_new ()
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 time;
-  GdkInputSource source;
-  guint32 deviceid;
-};
+  return GTK_WIDGET ( gtk_type_new (tictactoe_get_type ()));
+}
 
-struct _GdkEventDragRequest
+void          
+tictactoe_clear (Tictactoe *ttt)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint sendreply:1;
-      guint willaccept:1;
-      guint delete_data:1; /* Do *not* delete if link is sent, only
-                              if data is sent */
-      guint senddata:1;
-      guint reserved:22;
-    } flags;
-    glong allflags;
-  } u;
-  guint8 isdrop; /* This gdk event can be generated by a couple of
-                    X events - this lets the app know whether the
-                    drop really occurred or we just set the data */
+  int i,j;
 
-  GdkPoint drop_coords;
-  gchar *data_type;
-  guint32 timestamp;
-};
+  for (i=0;i<3;i++)
+    for (j=0;j<3;j++)
+      {
+       gtk_signal_handler_block_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
+       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
+                                    FALSE);
+       gtk_signal_handler_unblock_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
+      }
+}
 
-struct _GdkEventDragBegin
+static void
+tictactoe_toggle (GtkWidget *widget, Tictactoe *ttt)
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint reserved:28;
-    } flags;
-    glong allflags;
-  } u;
-};
+  int i,k;
 
-struct _GdkEventDropEnter
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint sendreply:1;
-      guint extended_typelist:1;
-      guint reserved:26;
-    } flags;
-    glong allflags;
-  } u;
-};
+  static int rwins[8][3] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
+                            { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
+                            { 0, 1, 2 }, { 0, 1, 2 } };
+  static int cwins[8][3] = { { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
+                            { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
+                            { 0, 1, 2 }, { 2, 1, 0 } };
 
-struct _GdkEventDropLeave
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint reserved:28;
-    } flags;
-    glong allflags;
-  } u;
-};
+  int success, found;
 
-struct _GdkEventDropDataAvailable
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  guint32 requestor;
-  union {
-    struct {
-      guint protocol_version:4;
-      guint isdrop:1;
-      guint reserved:25;
-    } flags;
-    glong allflags;
-  } u;
-  gchar *data_type; /* MIME type */
-  gulong data_numbytes;
-  gpointer data;
-  guint32 timestamp;
-  GdkPoint coords;
-};
+  for (k=0; k<8; k++)
+    {
+      success = TRUE;
+      found = FALSE;
 
-struct _GdkEventClient
-{
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkAtom message_type;
-  gushort data_format;
-  union {
-    char b[20];
-    short s[10];
-    long l[5];
-  } data;
-};
+      for (i=0;i<3;i++)
+       {
+         success = success &amp;&amp; 
+           GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
+         found = found ||
+           ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
+       }
+      
+      if (success &amp;&amp; found)
+       {
+         gtk_signal_emit (GTK_OBJECT (ttt), 
+                          tictactoe_signals[TICTACTOE_SIGNAL]);
+         break;
+       }
+    }
+}
+
+/* example-end */
+</verb></tscreen>
+
+<!-- ----------------------------------------------------------------- -->
+<sect2>ttt_test.c
+<p>
+<tscreen><verb>
+/* example-start tictactoe ttt_test.c */
+
+#include <gtk/gtk.h>
+#include "tictactoe.h"
+
+void
+win (GtkWidget *widget, gpointer data)
+{
+  g_print ("Yay!\n");
+  tictactoe_clear (TICTACTOE (widget));
+}
 
-struct _GdkEventOther
+int 
+main (int argc, char *argv[])
 {
-  GdkEventType type;
-  GdkWindow *window;
-  gint8 send_event;
-  GdkXEvent *xevent;
-};
-</verb></tscreen>
+  GtkWidget *window;
+  GtkWidget *ttt;
+  
+  gtk_init (&amp;argc, &amp;argv);
 
-<!-- ***************************************************************** -->
-<sect> Code Examples
-<!-- ***************************************************************** -->
-<p>
-Below are the code examples that are used in the above text
-which are not included in complete form elsewhere.
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  
+  gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
+  
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (gtk_exit), NULL);
+  
+  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+
+  ttt = tictactoe_new ();
+  
+  gtk_container_add (GTK_CONTAINER (window), ttt);
+  gtk_widget_show (ttt);
+
+  gtk_signal_connect (GTK_OBJECT (ttt), "tictactoe",
+                     GTK_SIGNAL_FUNC (win), NULL);
+
+  gtk_widget_show (window);
+  
+  gtk_main ();
+  
+  return 0;
+}
+
+/* example-end */
+</verb></tscreen>
 
 <!-- ----------------------------------------------------------------- -->
-<sect1>Tictactoe
+<sect1> GtkDial
+
 <!-- ----------------------------------------------------------------- -->
-<sect2>tictactoe.h
+<sect2> gtkdial.h
 <p>
 <tscreen><verb>
-/* example-start tictactoe tictactoe.h */
+/* example-start gtkdial gtkdial.h */
 
 /* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
@@ -14484,58 +14378,85 @@ which are not included in complete form elsewhere.
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#ifndef __TICTACTOE_H__
-#define __TICTACTOE_H__
+#ifndef __GTK_DIAL_H__
+#define __GTK_DIAL_H__
 
 
 #include <gdk/gdk.h>
-#include <gtk/gtkvbox.h>
+#include <gtk/gtkadjustment.h>
+#include <gtk/gtkwidget.h>
 
 
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
 
-#define TICTACTOE(obj)          GTK_CHECK_CAST (obj, tictactoe_get_type (), Tictactoe)
-#define TICTACTOE_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, tictactoe_get_type (), TictactoeClass)
-#define IS_TICTACTOE(obj)       GTK_CHECK_TYPE (obj, tictactoe_get_type ())
 
+#define GTK_DIAL(obj)          GTK_CHECK_CAST (obj, gtk_dial_get_type (), GtkDial)
+#define GTK_DIAL_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_dial_get_type (), GtkDialClass)
+#define GTK_IS_DIAL(obj)       GTK_CHECK_TYPE (obj, gtk_dial_get_type ())
 
-typedef struct _Tictactoe       Tictactoe;
-typedef struct _TictactoeClass  TictactoeClass;
 
-struct _Tictactoe
+typedef struct _GtkDial        GtkDial;
+typedef struct _GtkDialClass   GtkDialClass;
+
+struct _GtkDial
 {
-  GtkVBox vbox;
-  
-  GtkWidget *buttons[3][3];
+  GtkWidget widget;
+
+  /* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
+  guint policy : 2;
+
+  /* Button currently pressed or 0 if none */
+  guint8 button;
+
+  /* Dimensions of dial components */
+  gint radius;
+  gint pointer_width;
+
+  /* ID of update timer, or 0 if none */
+  guint32 timer;
+
+  /* Current angle */
+  gfloat angle;
+
+  /* Old values from adjustment stored so we know when something changes */
+  gfloat old_value;
+  gfloat old_lower;
+  gfloat old_upper;
+
+  /* The adjustment object that stores the data for this dial */
+  GtkAdjustment *adjustment;
 };
 
-struct _TictactoeClass
+struct _GtkDialClass
 {
-  GtkVBoxClass parent_class;
-
-  void (* tictactoe) (Tictactoe *ttt);
+  GtkWidgetClass parent_class;
 };
 
-guint          tictactoe_get_type        (void);
-GtkWidget*     tictactoe_new             (void);
-void          tictactoe_clear           (Tictactoe *ttt);
 
+GtkWidget*     gtk_dial_new                    (GtkAdjustment *adjustment);
+guint          gtk_dial_get_type               (void);
+GtkAdjustment* gtk_dial_get_adjustment         (GtkDial      *dial);
+void           gtk_dial_set_update_policy      (GtkDial      *dial,
+                                               GtkUpdateType  policy);
+
+void           gtk_dial_set_adjustment         (GtkDial      *dial,
+                                               GtkAdjustment *adjustment);
 #ifdef __cplusplus
 }
 #endif /* __cplusplus */
 
-#endif /* __TICTACTOE_H__ */
 
+#endif /* __GTK_DIAL_H__ */
 /* example-end */
 </verb></tscreen>
 
 <!-- ----------------------------------------------------------------- -->
-<sect2>tictactoe.c
+<sect2> gtkdial.c
 <p>
 <tscreen><verb>
-/* example-start tictactoe tictactoe.c */
+/* example-start gtkdial gtkdial.c */
 
 /* GTK - The GIMP Toolkit
  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
@@ -14555,1082 +14476,1379 @@ void             tictactoe_clear           (Tictactoe *ttt);
  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  * Boston, MA 02111-1307, USA.
  */
-#include "gtk/gtksignal.h"
-#include "gtk/gtktable.h"
-#include "gtk/gtktogglebutton.h"
-#include "tictactoe.h"
+#include <math.h>
+#include <stdio.h>
+#include <gtk/gtkmain.h>
+#include <gtk/gtksignal.h>
 
-enum {
-  TICTACTOE_SIGNAL,
-  LAST_SIGNAL
-};
+#include "gtkdial.h"
 
-static void tictactoe_class_init          (TictactoeClass *klass);
-static void tictactoe_init                (Tictactoe      *ttt);
-static void tictactoe_toggle              (GtkWidget *widget, Tictactoe *ttt);
+#define SCROLL_DELAY_LENGTH  300
+#define DIAL_DEFAULT_SIZE 100
 
-static gint tictactoe_signals[LAST_SIGNAL] = { 0 };
+/* Forward declarations */
+
+static void gtk_dial_class_init               (GtkDialClass    *klass);
+static void gtk_dial_init                     (GtkDial         *dial);
+static void gtk_dial_destroy                  (GtkObject        *object);
+static void gtk_dial_realize                  (GtkWidget        *widget);
+static void gtk_dial_size_request             (GtkWidget      *widget,
+                                              GtkRequisition *requisition);
+static void gtk_dial_size_allocate            (GtkWidget     *widget,
+                                              GtkAllocation *allocation);
+static gint gtk_dial_expose                   (GtkWidget        *widget,
+                                               GdkEventExpose   *event);
+static gint gtk_dial_button_press             (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gint gtk_dial_button_release           (GtkWidget        *widget,
+                                               GdkEventButton   *event);
+static gint gtk_dial_motion_notify            (GtkWidget        *widget,
+                                               GdkEventMotion   *event);
+static gint gtk_dial_timer                    (GtkDial         *dial);
+
+static void gtk_dial_update_mouse             (GtkDial *dial, gint x, gint y);
+static void gtk_dial_update                   (GtkDial *dial);
+static void gtk_dial_adjustment_changed       (GtkAdjustment    *adjustment,
+                                               gpointer          data);
+static void gtk_dial_adjustment_value_changed (GtkAdjustment    *adjustment,
+                                               gpointer          data);
+
+/* Local data */
+
+static GtkWidgetClass *parent_class = NULL;
 
 guint
-tictactoe_get_type ()
+gtk_dial_get_type ()
 {
-  static guint ttt_type = 0;
+  static guint dial_type = 0;
 
-  if (!ttt_type)
+  if (!dial_type)
     {
-      GtkTypeInfo ttt_info =
+      GtkTypeInfo dial_info =
       {
-       "Tictactoe",
-       sizeof (Tictactoe),
-       sizeof (TictactoeClass),
-       (GtkClassInitFunc) tictactoe_class_init,
-       (GtkObjectInitFunc) tictactoe_init,
-        (GtkArgSetFunc) NULL,
-        (GtkArgGetFunc) NULL
+       "GtkDial",
+       sizeof (GtkDial),
+       sizeof (GtkDialClass),
+       (GtkClassInitFunc) gtk_dial_class_init,
+       (GtkObjectInitFunc) gtk_dial_init,
+       (GtkArgSetFunc) NULL,
+       (GtkArgGetFunc) NULL,
       };
 
-      ttt_type = gtk_type_unique (gtk_vbox_get_type (), &amp;ttt_info);
+      dial_type = gtk_type_unique (gtk_widget_get_type (), &amp;dial_info);
     }
 
-  return ttt_type;
+  return dial_type;
 }
 
 static void
-tictactoe_class_init (TictactoeClass *class)
+gtk_dial_class_init (GtkDialClass *class)
 {
   GtkObjectClass *object_class;
+  GtkWidgetClass *widget_class;
+
+  object_class = (GtkObjectClass*) class;
+  widget_class = (GtkWidgetClass*) class;
+
+  parent_class = gtk_type_class (gtk_widget_get_type ());
+
+  object_class->destroy = gtk_dial_destroy;
+
+  widget_class->realize = gtk_dial_realize;
+  widget_class->expose_event = gtk_dial_expose;
+  widget_class->size_request = gtk_dial_size_request;
+  widget_class->size_allocate = gtk_dial_size_allocate;
+  widget_class->button_press_event = gtk_dial_button_press;
+  widget_class->button_release_event = gtk_dial_button_release;
+  widget_class->motion_notify_event = gtk_dial_motion_notify;
+}
+
+static void
+gtk_dial_init (GtkDial *dial)
+{
+  dial->button = 0;
+  dial->policy = GTK_UPDATE_CONTINUOUS;
+  dial->timer = 0;
+  dial->radius = 0;
+  dial->pointer_width = 0;
+  dial->angle = 0.0;
+  dial->old_value = 0.0;
+  dial->old_lower = 0.0;
+  dial->old_upper = 0.0;
+  dial->adjustment = NULL;
+}
+
+GtkWidget*
+gtk_dial_new (GtkAdjustment *adjustment)
+{
+  GtkDial *dial;
+
+  dial = gtk_type_new (gtk_dial_get_type ());
+
+  if (!adjustment)
+    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+
+  gtk_dial_set_adjustment (dial, adjustment);
+
+  return GTK_WIDGET (dial);
+}
+
+static void
+gtk_dial_destroy (GtkObject *object)
+{
+  GtkDial *dial;
 
-  object_class = (GtkObjectClass*) class;
-  
-  tictactoe_signals[TICTACTOE_SIGNAL] = gtk_signal_new ("tictactoe",
-                                        GTK_RUN_FIRST,
-                                        object_class->type,
-                                        GTK_SIGNAL_OFFSET (TictactoeClass, tictactoe),
-                                        gtk_signal_default_marshaller, GTK_TYPE_NONE, 0);
+  g_return_if_fail (object != NULL);
+  g_return_if_fail (GTK_IS_DIAL (object));
 
+  dial = GTK_DIAL (object);
 
-  gtk_object_class_add_signals (object_class, tictactoe_signals, LAST_SIGNAL);
+  if (dial->adjustment)
+    gtk_object_unref (GTK_OBJECT (dial->adjustment));
 
-  class->tictactoe = NULL;
+  if (GTK_OBJECT_CLASS (parent_class)->destroy)
+    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
 }
 
-static void
-tictactoe_init (Tictactoe *ttt)
+GtkAdjustment*
+gtk_dial_get_adjustment (GtkDial *dial)
 {
-  GtkWidget *table;
-  gint i,j;
-  
-  table = gtk_table_new (3, 3, TRUE);
-  gtk_container_add (GTK_CONTAINER(ttt), table);
-  gtk_widget_show (table);
+  g_return_val_if_fail (dial != NULL, NULL);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);
 
-  for (i=0;i<3; i++)
-    for (j=0;j<3; j++)
-      {
-       ttt->buttons[i][j] = gtk_toggle_button_new ();
-       gtk_table_attach_defaults (GTK_TABLE(table), ttt->buttons[i][j], 
-                                  i, i+1, j, j+1);
-       gtk_signal_connect (GTK_OBJECT (ttt->buttons[i][j]), "toggled",
-                           GTK_SIGNAL_FUNC (tictactoe_toggle), ttt);
-       gtk_widget_set_usize (ttt->buttons[i][j], 20, 20);
-       gtk_widget_show (ttt->buttons[i][j]);
-      }
+  return dial->adjustment;
 }
 
-GtkWidget*
-tictactoe_new ()
+void
+gtk_dial_set_update_policy (GtkDial      *dial,
+                            GtkUpdateType  policy)
 {
-  return GTK_WIDGET ( gtk_type_new (tictactoe_get_type ()));
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
+
+  dial->policy = policy;
 }
 
-void          
-tictactoe_clear (Tictactoe *ttt)
+void
+gtk_dial_set_adjustment (GtkDial      *dial,
+                         GtkAdjustment *adjustment)
 {
-  int i,j;
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
 
-  for (i=0;i<3;i++)
-    for (j=0;j<3;j++)
-      {
-       gtk_signal_handler_block_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
-       gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (ttt->buttons[i][j]),
-                                    FALSE);
-       gtk_signal_handler_unblock_by_data (GTK_OBJECT(ttt->buttons[i][j]), ttt);
-      }
+  if (dial->adjustment)
+    {
+      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), (gpointer) dial);
+      gtk_object_unref (GTK_OBJECT (dial->adjustment));
+    }
+
+  dial->adjustment = adjustment;
+  gtk_object_ref (GTK_OBJECT (dial->adjustment));
+
+  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
+                     (GtkSignalFunc) gtk_dial_adjustment_changed,
+                     (gpointer) dial);
+  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
+                     (GtkSignalFunc) gtk_dial_adjustment_value_changed,
+                     (gpointer) dial);
+
+  dial->old_value = adjustment->value;
+  dial->old_lower = adjustment->lower;
+  dial->old_upper = adjustment->upper;
+
+  gtk_dial_update (dial);
 }
 
 static void
-tictactoe_toggle (GtkWidget *widget, Tictactoe *ttt)
+gtk_dial_realize (GtkWidget *widget)
 {
-  int i,k;
+  GtkDial *dial;
+  GdkWindowAttr attributes;
+  gint attributes_mask;
 
-  static int rwins[8][3] = { { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
-                            { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
-                            { 0, 1, 2 }, { 0, 1, 2 } };
-  static int cwins[8][3] = { { 0, 1, 2 }, { 0, 1, 2 }, { 0, 1, 2 },
-                            { 0, 0, 0 }, { 1, 1, 1 }, { 2, 2, 2 },
-                            { 0, 1, 2 }, { 2, 1, 0 } };
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DIAL (widget));
 
-  int success, found;
+  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
+  dial = GTK_DIAL (widget);
 
-  for (k=0; k<8; k++)
-    {
-      success = TRUE;
-      found = FALSE;
+  attributes.x = widget->allocation.x;
+  attributes.y = widget->allocation.y;
+  attributes.width = widget->allocation.width;
+  attributes.height = widget->allocation.height;
+  attributes.wclass = GDK_INPUT_OUTPUT;
+  attributes.window_type = GDK_WINDOW_CHILD;
+  attributes.event_mask = gtk_widget_get_events (widget) | 
+    GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
+    GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
+    GDK_POINTER_MOTION_HINT_MASK;
+  attributes.visual = gtk_widget_get_visual (widget);
+  attributes.colormap = gtk_widget_get_colormap (widget);
 
-      for (i=0;i<3;i++)
-       {
-         success = success &amp;&amp; 
-           GTK_TOGGLE_BUTTON(ttt->buttons[rwins[k][i]][cwins[k][i]])->active;
-         found = found ||
-           ttt->buttons[rwins[k][i]][cwins[k][i]] == widget;
-       }
-      
-      if (success &amp;&amp; found)
-       {
-         gtk_signal_emit (GTK_OBJECT (ttt), 
-                          tictactoe_signals[TICTACTOE_SIGNAL]);
-         break;
-       }
-    }
-}
+  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
+  widget->window = gdk_window_new (widget->parent->window, &amp;attributes, attributes_mask);
 
-/* example-end */
-</verb></tscreen>
+  widget->style = gtk_style_attach (widget->style, widget->window);
 
-<!-- ----------------------------------------------------------------- -->
-<sect2>ttt_test.c
-<p>
-<tscreen><verb>
-/* example-start tictactoe ttt_test.c */
+  gdk_window_set_user_data (widget->window, widget);
 
-#include <gtk/gtk.h>
-#include "tictactoe.h"
+  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+}
 
-void
-win (GtkWidget *widget, gpointer data)
+static void 
+gtk_dial_size_request (GtkWidget      *widget,
+                      GtkRequisition *requisition)
 {
-  g_print ("Yay!\n");
-  tictactoe_clear (TICTACTOE (widget));
+  requisition->width = DIAL_DEFAULT_SIZE;
+  requisition->height = DIAL_DEFAULT_SIZE;
 }
 
-int 
-main (int argc, char *argv[])
+static void
+gtk_dial_size_allocate (GtkWidget     *widget,
+                       GtkAllocation *allocation)
 {
-  GtkWidget *window;
-  GtkWidget *ttt;
-  
-  gtk_init (&amp;argc, &amp;argv);
+  GtkDial *dial;
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  
-  gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
-  
-  gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                     GTK_SIGNAL_FUNC (gtk_exit), NULL);
-  
-  gtk_container_set_border_width (GTK_CONTAINER (window), 10);
+  g_return_if_fail (widget != NULL);
+  g_return_if_fail (GTK_IS_DIAL (widget));
+  g_return_if_fail (allocation != NULL);
 
-  ttt = tictactoe_new ();
-  
-  gtk_container_add (GTK_CONTAINER (window), ttt);
-  gtk_widget_show (ttt);
+  widget->allocation = *allocation;
+  dial = GTK_DIAL (widget);
 
-  gtk_signal_connect (GTK_OBJECT (ttt), "tictactoe",
-                     GTK_SIGNAL_FUNC (win), NULL);
+  if (GTK_WIDGET_REALIZED (widget))
+    {
 
-  gtk_widget_show (window);
-  
-  gtk_main ();
-  
-  return 0;
+      gdk_window_move_resize (widget->window,
+                             allocation->x, allocation->y,
+                             allocation->width, allocation->height);
+
+    }
+  dial->radius = MIN(allocation->width,allocation->height) * 0.45;
+  dial->pointer_width = dial->radius / 5;
 }
 
-/* example-end */
-</verb></tscreen>
+static gint
+gtk_dial_expose (GtkWidget      *widget,
+                GdkEventExpose *event)
+{
+  GtkDial *dial;
+  GdkPoint points[3];
+  gdouble s,c;
+  gdouble theta;
+  gint xc, yc;
+  gint tick_length;
+  gint i;
 
-<!-- ----------------------------------------------------------------- -->
-<sect1> GtkDial
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-<!-- ----------------------------------------------------------------- -->
-<sect2> gtkdial.h
-<p>
-<tscreen><verb>
-/* example-start gtkdial gtkdial.h */
+  if (event->count > 0)
+    return FALSE;
+  
+  dial = GTK_DIAL (widget);
 
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#ifndef __GTK_DIAL_H__
-#define __GTK_DIAL_H__
+  gdk_window_clear_area (widget->window,
+                        0, 0,
+                        widget->allocation.width,
+                        widget->allocation.height);
+
+  xc = widget->allocation.width/2;
+  yc = widget->allocation.height/2;
 
+  /* Draw ticks */
 
-#include <gdk/gdk.h>
-#include <gtk/gtkadjustment.h>
-#include <gtk/gtkwidget.h>
+  for (i=0; i<25; i++)
+    {
+      theta = (i*M_PI/18. - M_PI/6.);
+      s = sin(theta);
+      c = cos(theta);
 
+      tick_length = (i%6 == 0) ? dial->pointer_width : dial->pointer_width/2;
+      
+      gdk_draw_line (widget->window,
+                    widget->style->fg_gc[widget->state],
+                    xc + c*(dial->radius - tick_length),
+                    yc - s*(dial->radius - tick_length),
+                    xc + c*dial->radius,
+                    yc - s*dial->radius);
+    }
 
-#ifdef __cplusplus
-extern "C" {
-#endif /* __cplusplus */
+  /* Draw pointer */
 
+  s = sin(dial->angle);
+  c = cos(dial->angle);
 
-#define GTK_DIAL(obj)          GTK_CHECK_CAST (obj, gtk_dial_get_type (), GtkDial)
-#define GTK_DIAL_CLASS(klass)  GTK_CHECK_CLASS_CAST (klass, gtk_dial_get_type (), GtkDialClass)
-#define GTK_IS_DIAL(obj)       GTK_CHECK_TYPE (obj, gtk_dial_get_type ())
 
+  points[0].x = xc + s*dial->pointer_width/2;
+  points[0].y = yc + c*dial->pointer_width/2;
+  points[1].x = xc + c*dial->radius;
+  points[1].y = yc - s*dial->radius;
+  points[2].x = xc - s*dial->pointer_width/2;
+  points[2].y = yc - c*dial->pointer_width/2;
 
-typedef struct _GtkDial        GtkDial;
-typedef struct _GtkDialClass   GtkDialClass;
+  gtk_draw_polygon (widget->style,
+                   widget->window,
+                   GTK_STATE_NORMAL,
+                   GTK_SHADOW_OUT,
+                   points, 3,
+                   TRUE);
+  
+  return FALSE;
+}
 
-struct _GtkDial
+static gint
+gtk_dial_button_press (GtkWidget      *widget,
+                      GdkEventButton *event)
 {
-  GtkWidget widget;
-
-  /* update policy (GTK_UPDATE_[CONTINUOUS/DELAYED/DISCONTINUOUS]) */
-  guint policy : 2;
+  GtkDial *dial;
+  gint dx, dy;
+  double s, c;
+  double d_parallel;
+  double d_perpendicular;
 
-  /* Button currently pressed or 0 if none */
-  guint8 button;
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-  /* Dimensions of dial components */
-  gint radius;
-  gint pointer_width;
+  dial = GTK_DIAL (widget);
 
-  /* ID of update timer, or 0 if none */
-  guint32 timer;
+  /* Determine if button press was within pointer region - we 
+     do this by computing the parallel and perpendicular distance of
+     the point where the mouse was pressed from the line passing through
+     the pointer */
+  
+  dx = event->x - widget->allocation.width / 2;
+  dy = widget->allocation.height / 2 - event->y;
+  
+  s = sin(dial->angle);
+  c = cos(dial->angle);
+  
+  d_parallel = s*dy + c*dx;
+  d_perpendicular = fabs(s*dx - c*dy);
+  
+  if (!dial->button &amp;&amp;
+      (d_perpendicular < dial->pointer_width/2) &amp;&amp;
+      (d_parallel > - dial->pointer_width))
+    {
+      gtk_grab_add (widget);
 
-  /* Current angle */
-  gfloat angle;
+      dial->button = event->button;
 
-  /* Old values from adjustment stored so we know when something changes */
-  gfloat old_value;
-  gfloat old_lower;
-  gfloat old_upper;
+      gtk_dial_update_mouse (dial, event->x, event->y);
+    }
 
-  /* The adjustment object that stores the data for this dial */
-  GtkAdjustment *adjustment;
-};
+  return FALSE;
+}
 
-struct _GtkDialClass
+static gint
+gtk_dial_button_release (GtkWidget      *widget,
+                         GdkEventButton *event)
 {
-  GtkWidgetClass parent_class;
-};
+  GtkDial *dial;
 
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-GtkWidget*     gtk_dial_new                    (GtkAdjustment *adjustment);
-guint          gtk_dial_get_type               (void);
-GtkAdjustment* gtk_dial_get_adjustment         (GtkDial      *dial);
-void           gtk_dial_set_update_policy      (GtkDial      *dial,
-                                               GtkUpdateType  policy);
+  dial = GTK_DIAL (widget);
 
-void           gtk_dial_set_adjustment         (GtkDial      *dial,
-                                               GtkAdjustment *adjustment);
-#ifdef __cplusplus
-}
-#endif /* __cplusplus */
+  if (dial->button == event->button)
+    {
+      gtk_grab_remove (widget);
 
+      dial->button = 0;
 
-#endif /* __GTK_DIAL_H__ */
-/* example-end */
-</verb></tscreen>
+      if (dial->policy == GTK_UPDATE_DELAYED)
+       gtk_timeout_remove (dial->timer);
+      
+      if ((dial->policy != GTK_UPDATE_CONTINUOUS) &amp;&amp;
+         (dial->old_value != dial->adjustment->value))
+       gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    }
 
-<!-- ----------------------------------------------------------------- -->
-<sect2> gtkdial.c
-<p>
-<tscreen><verb>
-/* example-start gtkdial gtkdial.c */
+  return FALSE;
+}
 
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
- */
-#include <math.h>
-#include <stdio.h>
-#include <gtk/gtkmain.h>
-#include <gtk/gtksignal.h>
+static gint
+gtk_dial_motion_notify (GtkWidget      *widget,
+                        GdkEventMotion *event)
+{
+  GtkDial *dial;
+  GdkModifierType mods;
+  gint x, y, mask;
 
-#include "gtkdial.h"
+  g_return_val_if_fail (widget != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
+  g_return_val_if_fail (event != NULL, FALSE);
 
-#define SCROLL_DELAY_LENGTH  300
-#define DIAL_DEFAULT_SIZE 100
+  dial = GTK_DIAL (widget);
 
-/* Forward declarations */
+  if (dial->button != 0)
+    {
+      x = event->x;
+      y = event->y;
 
-static void gtk_dial_class_init               (GtkDialClass    *klass);
-static void gtk_dial_init                     (GtkDial         *dial);
-static void gtk_dial_destroy                  (GtkObject        *object);
-static void gtk_dial_realize                  (GtkWidget        *widget);
-static void gtk_dial_size_request             (GtkWidget      *widget,
-                                              GtkRequisition *requisition);
-static void gtk_dial_size_allocate            (GtkWidget     *widget,
-                                              GtkAllocation *allocation);
-static gint gtk_dial_expose                   (GtkWidget        *widget,
-                                               GdkEventExpose   *event);
-static gint gtk_dial_button_press             (GtkWidget        *widget,
-                                               GdkEventButton   *event);
-static gint gtk_dial_button_release           (GtkWidget        *widget,
-                                               GdkEventButton   *event);
-static gint gtk_dial_motion_notify            (GtkWidget        *widget,
-                                               GdkEventMotion   *event);
-static gint gtk_dial_timer                    (GtkDial         *dial);
+      if (event->is_hint || (event->window != widget->window))
+       gdk_window_get_pointer (widget->window, &amp;x, &amp;y, &amp;mods);
 
-static void gtk_dial_update_mouse             (GtkDial *dial, gint x, gint y);
-static void gtk_dial_update                   (GtkDial *dial);
-static void gtk_dial_adjustment_changed       (GtkAdjustment    *adjustment,
-                                               gpointer          data);
-static void gtk_dial_adjustment_value_changed (GtkAdjustment    *adjustment,
-                                               gpointer          data);
+      switch (dial->button)
+       {
+       case 1:
+         mask = GDK_BUTTON1_MASK;
+         break;
+       case 2:
+         mask = GDK_BUTTON2_MASK;
+         break;
+       case 3:
+         mask = GDK_BUTTON3_MASK;
+         break;
+       default:
+         mask = 0;
+         break;
+       }
 
-/* Local data */
+      if (mods &amp; mask)
+       gtk_dial_update_mouse (dial, x,y);
+    }
 
-static GtkWidgetClass *parent_class = NULL;
+  return FALSE;
+}
 
-guint
-gtk_dial_get_type ()
+static gint
+gtk_dial_timer (GtkDial *dial)
 {
-  static guint dial_type = 0;
-
-  if (!dial_type)
-    {
-      GtkTypeInfo dial_info =
-      {
-       "GtkDial",
-       sizeof (GtkDial),
-       sizeof (GtkDialClass),
-       (GtkClassInitFunc) gtk_dial_class_init,
-       (GtkObjectInitFunc) gtk_dial_init,
-       (GtkArgSetFunc) NULL,
-       (GtkArgGetFunc) NULL,
-      };
+  g_return_val_if_fail (dial != NULL, FALSE);
+  g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
 
-      dial_type = gtk_type_unique (gtk_widget_get_type (), &amp;dial_info);
-    }
+  if (dial->policy == GTK_UPDATE_DELAYED)
+    gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
 
-  return dial_type;
+  return FALSE;
 }
 
 static void
-gtk_dial_class_init (GtkDialClass *class)
+gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
 {
-  GtkObjectClass *object_class;
-  GtkWidgetClass *widget_class;
+  gint xc, yc;
+  gfloat old_value;
 
-  object_class = (GtkObjectClass*) class;
-  widget_class = (GtkWidgetClass*) class;
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
 
-  parent_class = gtk_type_class (gtk_widget_get_type ());
+  xc = GTK_WIDGET(dial)->allocation.width / 2;
+  yc = GTK_WIDGET(dial)->allocation.height / 2;
 
-  object_class->destroy = gtk_dial_destroy;
+  old_value = dial->adjustment->value;
+  dial->angle = atan2(yc-y, x-xc);
 
-  widget_class->realize = gtk_dial_realize;
-  widget_class->expose_event = gtk_dial_expose;
-  widget_class->size_request = gtk_dial_size_request;
-  widget_class->size_allocate = gtk_dial_size_allocate;
-  widget_class->button_press_event = gtk_dial_button_press;
-  widget_class->button_release_event = gtk_dial_button_release;
-  widget_class->motion_notify_event = gtk_dial_motion_notify;
-}
+  if (dial->angle < -M_PI/2.)
+    dial->angle += 2*M_PI;
 
-static void
-gtk_dial_init (GtkDial *dial)
-{
-  dial->button = 0;
-  dial->policy = GTK_UPDATE_CONTINUOUS;
-  dial->timer = 0;
-  dial->radius = 0;
-  dial->pointer_width = 0;
-  dial->angle = 0.0;
-  dial->old_value = 0.0;
-  dial->old_lower = 0.0;
-  dial->old_upper = 0.0;
-  dial->adjustment = NULL;
-}
+  if (dial->angle < -M_PI/6)
+    dial->angle = -M_PI/6;
 
-GtkWidget*
-gtk_dial_new (GtkAdjustment *adjustment)
-{
-  GtkDial *dial;
+  if (dial->angle > 7.*M_PI/6.)
+    dial->angle = 7.*M_PI/6.;
 
-  dial = gtk_type_new (gtk_dial_get_type ());
+  dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
+    (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
 
-  if (!adjustment)
-    adjustment = (GtkAdjustment*) gtk_adjustment_new (0.0, 0.0, 0.0, 0.0, 0.0, 0.0);
+  if (dial->adjustment->value != old_value)
+    {
+      if (dial->policy == GTK_UPDATE_CONTINUOUS)
+       {
+         gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+       }
+      else
+       {
+         gtk_widget_draw (GTK_WIDGET(dial), NULL);
 
-  gtk_dial_set_adjustment (dial, adjustment);
+         if (dial->policy == GTK_UPDATE_DELAYED)
+           {
+             if (dial->timer)
+               gtk_timeout_remove (dial->timer);
 
-  return GTK_WIDGET (dial);
+             dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
+                                            (GtkFunction) gtk_dial_timer,
+                                            (gpointer) dial);
+           }
+       }
+    }
 }
 
 static void
-gtk_dial_destroy (GtkObject *object)
+gtk_dial_update (GtkDial *dial)
 {
-  GtkDial *dial;
-
-  g_return_if_fail (object != NULL);
-  g_return_if_fail (GTK_IS_DIAL (object));
+  gfloat new_value;
+  
+  g_return_if_fail (dial != NULL);
+  g_return_if_fail (GTK_IS_DIAL (dial));
 
-  dial = GTK_DIAL (object);
+  new_value = dial->adjustment->value;
+  
+  if (new_value < dial->adjustment->lower)
+    new_value = dial->adjustment->lower;
 
-  if (dial->adjustment)
-    gtk_object_unref (GTK_OBJECT (dial->adjustment));
+  if (new_value > dial->adjustment->upper)
+    new_value = dial->adjustment->upper;
 
-  if (GTK_OBJECT_CLASS (parent_class)->destroy)
-    (* GTK_OBJECT_CLASS (parent_class)->destroy) (object);
-}
+  if (new_value != dial->adjustment->value)
+    {
+      dial->adjustment->value = new_value;
+      gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+    }
 
-GtkAdjustment*
-gtk_dial_get_adjustment (GtkDial *dial)
-{
-  g_return_val_if_fail (dial != NULL, NULL);
-  g_return_val_if_fail (GTK_IS_DIAL (dial), NULL);
+  dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
+    (dial->adjustment->upper - dial->adjustment->lower);
 
-  return dial->adjustment;
+  gtk_widget_draw (GTK_WIDGET(dial), NULL);
 }
 
-void
-gtk_dial_set_update_policy (GtkDial      *dial,
-                            GtkUpdateType  policy)
+static void
+gtk_dial_adjustment_changed (GtkAdjustment *adjustment,
+                             gpointer       data)
 {
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+  GtkDial *dial;
 
-  dial->policy = policy;
-}
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
 
-void
-gtk_dial_set_adjustment (GtkDial      *dial,
-                         GtkAdjustment *adjustment)
-{
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+  dial = GTK_DIAL (data);
 
-  if (dial->adjustment)
+  if ((dial->old_value != adjustment->value) ||
+      (dial->old_lower != adjustment->lower) ||
+      (dial->old_upper != adjustment->upper))
     {
-      gtk_signal_disconnect_by_data (GTK_OBJECT (dial->adjustment), (gpointer) dial);
-      gtk_object_unref (GTK_OBJECT (dial->adjustment));
-    }
-
-  dial->adjustment = adjustment;
-  gtk_object_ref (GTK_OBJECT (dial->adjustment));
-
-  gtk_signal_connect (GTK_OBJECT (adjustment), "changed",
-                     (GtkSignalFunc) gtk_dial_adjustment_changed,
-                     (gpointer) dial);
-  gtk_signal_connect (GTK_OBJECT (adjustment), "value_changed",
-                     (GtkSignalFunc) gtk_dial_adjustment_value_changed,
-                     (gpointer) dial);
-
-  dial->old_value = adjustment->value;
-  dial->old_lower = adjustment->lower;
-  dial->old_upper = adjustment->upper;
+      gtk_dial_update (dial);
 
-  gtk_dial_update (dial);
+      dial->old_value = adjustment->value;
+      dial->old_lower = adjustment->lower;
+      dial->old_upper = adjustment->upper;
+    }
 }
 
 static void
-gtk_dial_realize (GtkWidget *widget)
+gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
+                                   gpointer       data)
 {
   GtkDial *dial;
-  GdkWindowAttr attributes;
-  gint attributes_mask;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_DIAL (widget));
+  g_return_if_fail (adjustment != NULL);
+  g_return_if_fail (data != NULL);
 
-  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-  dial = GTK_DIAL (widget);
+  dial = GTK_DIAL (data);
 
-  attributes.x = widget->allocation.x;
-  attributes.y = widget->allocation.y;
-  attributes.width = widget->allocation.width;
-  attributes.height = widget->allocation.height;
-  attributes.wclass = GDK_INPUT_OUTPUT;
-  attributes.window_type = GDK_WINDOW_CHILD;
-  attributes.event_mask = gtk_widget_get_events (widget) | 
-    GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK | 
-    GDK_BUTTON_RELEASE_MASK | GDK_POINTER_MOTION_MASK |
-    GDK_POINTER_MOTION_HINT_MASK;
-  attributes.visual = gtk_widget_get_visual (widget);
-  attributes.colormap = gtk_widget_get_colormap (widget);
+  if (dial->old_value != adjustment->value)
+    {
+      gtk_dial_update (dial);
 
-  attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-  widget->window = gdk_window_new (widget->parent->window, &amp;attributes, attributes_mask);
+      dial->old_value = adjustment->value;
+    }
+}
+/* example-end */
+</verb></tscreen>
 
-  widget->style = gtk_style_attach (widget->style, widget->window);
+<!-- ----------------------------------------------------------------- -->
+<sect1> Scribble
+<p>
+<tscreen><verb>
+/* example-start scribble-simple scribble-simple.c */
 
-  gdk_window_set_user_data (widget->window, widget);
+/* GTK - The GIMP Toolkit
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
 
-  gtk_style_set_background (widget->style, widget->window, GTK_STATE_ACTIVE);
+#include <gtk/gtk.h>
+
+/* Backing pixmap for drawing area */
+static GdkPixmap *pixmap = NULL;
+
+/* Create a new backing pixmap of the appropriate size */
+static gint
+configure_event (GtkWidget *widget, GdkEventConfigure *event)
+{
+  if (pixmap)
+    gdk_pixmap_unref(pixmap);
+
+  pixmap = gdk_pixmap_new(widget->window,
+                         widget->allocation.width,
+                         widget->allocation.height,
+                         -1);
+  gdk_draw_rectangle (pixmap,
+                     widget->style->white_gc,
+                     TRUE,
+                     0, 0,
+                     widget->allocation.width,
+                     widget->allocation.height);
+
+  return TRUE;
 }
 
-static void 
-gtk_dial_size_request (GtkWidget      *widget,
-                      GtkRequisition *requisition)
+/* Redraw the screen from the backing pixmap */
+static gint
+expose_event (GtkWidget *widget, GdkEventExpose *event)
 {
-  requisition->width = DIAL_DEFAULT_SIZE;
-  requisition->height = DIAL_DEFAULT_SIZE;
+  gdk_draw_pixmap(widget->window,
+                 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
+                 pixmap,
+                 event->area.x, event->area.y,
+                 event->area.x, event->area.y,
+                 event->area.width, event->area.height);
+
+  return FALSE;
 }
 
+/* Draw a rectangle on the screen */
 static void
-gtk_dial_size_allocate (GtkWidget     *widget,
-                       GtkAllocation *allocation)
+draw_brush (GtkWidget *widget, gdouble x, gdouble y)
 {
-  GtkDial *dial;
+  GdkRectangle update_rect;
 
-  g_return_if_fail (widget != NULL);
-  g_return_if_fail (GTK_IS_DIAL (widget));
-  g_return_if_fail (allocation != NULL);
+  update_rect.x = x - 5;
+  update_rect.y = y - 5;
+  update_rect.width = 10;
+  update_rect.height = 10;
+  gdk_draw_rectangle (pixmap,
+                     widget->style->black_gc,
+                     TRUE,
+                     update_rect.x, update_rect.y,
+                     update_rect.width, update_rect.height);
+  gtk_widget_draw (widget, &amp;update_rect);
+}
 
-  widget->allocation = *allocation;
-  dial = GTK_DIAL (widget);
+static gint
+button_press_event (GtkWidget *widget, GdkEventButton *event)
+{
+  if (event->button == 1 &amp;&amp; pixmap != NULL)
+    draw_brush (widget, event->x, event->y);
 
-  if (GTK_WIDGET_REALIZED (widget))
-    {
+  return TRUE;
+}
 
-      gdk_window_move_resize (widget->window,
-                             allocation->x, allocation->y,
-                             allocation->width, allocation->height);
+static gint
+motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
+{
+  int x, y;
+  GdkModifierType state;
 
+  if (event->is_hint)
+    gdk_window_get_pointer (event->window, &amp;x, &amp;y, &amp;state);
+  else
+    {
+      x = event->x;
+      y = event->y;
+      state = event->state;
     }
-  dial->radius = MIN(allocation->width,allocation->height) * 0.45;
-  dial->pointer_width = dial->radius / 5;
+    
+  if (state &amp; GDK_BUTTON1_MASK &amp;&amp; pixmap != NULL)
+    draw_brush (widget, x, y);
+  
+  return TRUE;
 }
 
-static gint
-gtk_dial_expose (GtkWidget      *widget,
-                GdkEventExpose *event)
+void
+quit ()
 {
-  GtkDial *dial;
-  GdkPoint points[3];
-  gdouble s,c;
-  gdouble theta;
-  gint xc, yc;
-  gint tick_length;
-  gint i;
+  gtk_exit (0);
+}
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+int
+main (int argc, char *argv[])
+{
+  GtkWidget *window;
+  GtkWidget *drawing_area;
+  GtkWidget *vbox;
 
-  if (event->count > 0)
-    return FALSE;
-  
-  dial = GTK_DIAL (widget);
+  GtkWidget *button;
 
-  gdk_window_clear_area (widget->window,
-                        0, 0,
-                        widget->allocation.width,
-                        widget->allocation.height);
+  gtk_init (&amp;argc, &amp;argv);
 
-  xc = widget->allocation.width/2;
-  yc = widget->allocation.height/2;
+  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+  gtk_widget_set_name (window, "Test Input");
 
-  /* Draw ticks */
+  vbox = gtk_vbox_new (FALSE, 0);
+  gtk_container_add (GTK_CONTAINER (window), vbox);
+  gtk_widget_show (vbox);
 
-  for (i=0; i<25; i++)
-    {
-      theta = (i*M_PI/18. - M_PI/6.);
-      s = sin(theta);
-      c = cos(theta);
+  gtk_signal_connect (GTK_OBJECT (window), "destroy",
+                     GTK_SIGNAL_FUNC (quit), NULL);
 
-      tick_length = (i%6 == 0) ? dial->pointer_width : dial->pointer_width/2;
-      
-      gdk_draw_line (widget->window,
-                    widget->style->fg_gc[widget->state],
-                    xc + c*(dial->radius - tick_length),
-                    yc - s*(dial->radius - tick_length),
-                    xc + c*dial->radius,
-                    yc - s*dial->radius);
-    }
+  /* Create the drawing area */
 
-  /* Draw pointer */
+  drawing_area = gtk_drawing_area_new ();
+  gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
+  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
 
-  s = sin(dial->angle);
-  c = cos(dial->angle);
+  gtk_widget_show (drawing_area);
 
+  /* Signals used to handle backing pixmap */
 
-  points[0].x = xc + s*dial->pointer_width/2;
-  points[0].y = yc + c*dial->pointer_width/2;
-  points[1].x = xc + c*dial->radius;
-  points[1].y = yc - s*dial->radius;
-  points[2].x = xc - s*dial->pointer_width/2;
-  points[2].y = yc - c*dial->pointer_width/2;
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
+                     (GtkSignalFunc) expose_event, NULL);
+  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
+                     (GtkSignalFunc) configure_event, NULL);
 
-  gtk_draw_polygon (widget->style,
-                   widget->window,
-                   GTK_STATE_NORMAL,
-                   GTK_SHADOW_OUT,
-                   points, 3,
-                   TRUE);
-  
-  return FALSE;
-}
+  /* Event signals */
 
-static gint
-gtk_dial_button_press (GtkWidget      *widget,
-                      GdkEventButton *event)
-{
-  GtkDial *dial;
-  gint dx, dy;
-  double s, c;
-  double d_parallel;
-  double d_perpendicular;
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
+                     (GtkSignalFunc) motion_notify_event, NULL);
+  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
+                     (GtkSignalFunc) button_press_event, NULL);
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
+                        | GDK_LEAVE_NOTIFY_MASK
+                        | GDK_BUTTON_PRESS_MASK
+                        | GDK_POINTER_MOTION_MASK
+                        | GDK_POINTER_MOTION_HINT_MASK);
 
-  dial = GTK_DIAL (widget);
+  /* .. And a quit button */
+  button = gtk_button_new_with_label ("Quit");
+  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
 
-  /* Determine if button press was within pointer region - we 
-     do this by computing the parallel and perpendicular distance of
-     the point where the mouse was pressed from the line passing through
-     the pointer */
-  
-  dx = event->x - widget->allocation.width / 2;
-  dy = widget->allocation.height / 2 - event->y;
-  
-  s = sin(dial->angle);
-  c = cos(dial->angle);
-  
-  d_parallel = s*dy + c*dx;
-  d_perpendicular = fabs(s*dx - c*dy);
-  
-  if (!dial->button &amp;&amp;
-      (d_perpendicular < dial->pointer_width/2) &amp;&amp;
-      (d_parallel > - dial->pointer_width))
-    {
-      gtk_grab_add (widget);
+  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
+                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
+                            GTK_OBJECT (window));
+  gtk_widget_show (button);
 
-      dial->button = event->button;
+  gtk_widget_show (window);
 
-      gtk_dial_update_mouse (dial, event->x, event->y);
-    }
+  gtk_main ();
 
-  return FALSE;
+  return 0;
 }
+/* example-end */
+</verb></tscreen>
 
-static gint
-gtk_dial_button_release (GtkWidget      *widget,
-                         GdkEventButton *event)
+<!-- ***************************************************************** -->
+<sect> List Widget
+<!-- ***************************************************************** -->
+<p>
+NOTE: The GtkList widget has been superseded by the GtkCList
+widget. It is detailed here just for completeness.
+
+The GtkList widget is designed to act as a vertical container for
+widgets that should be of the type GtkListItem.
+
+A GtkList widget has its own window to receive events and its own
+background color which is usually white. As it is directly derived
+from a GtkContainer it can be treated as such by using the
+GTK_CONTAINER(List) macro, see the GtkContainer widget for more on
+this. One should already be familiar with the usage of a GList and
+its related functions g_list_*() to be able to use the GtkList widget
+to it full extent.
+
+There is one field inside the structure definition of the GtkList
+widget that will be of greater interest to us, this is:
+
+<tscreen><verb>
+struct _GtkList
 {
-  GtkDial *dial;
+  ...
+  GList *selection;
+  guint selection_mode;
+  ...
+}; 
+</verb></tscreen>
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+The selection field of a GtkList points to a linked list of all items
+that are currently selected, or NULL if the selection is empty.  So to
+learn about the current selection we read the GTK_LIST()->selection
+field, but do not modify it since the internal fields are maintained
+by the gtk_list_*() functions.
 
-  dial = GTK_DIAL (widget);
+The selection_mode of the GtkList determines the selection facilities
+of a GtkList and therefore the contents of the GTK_LIST()->selection
+field. The selection_mode may be one of the following:
 
-  if (dial->button == event->button)
-    {
-      gtk_grab_remove (widget);
+<itemize>
+<item> GTK_SELECTION_SINGLE - The selection is either NULL
+                        or contains a GList pointer
+                        for a single selected item.
 
-      dial->button = 0;
+<item> GTK_SELECTION_BROWSE -  The selection is NULL if the list
+                        contains no widgets or insensitive
+                        ones only, otherwise it contains
+                        a GList pointer for one GList
+                        structure, and therefore exactly
+                        one list item.
 
-      if (dial->policy == GTK_UPDATE_DELAYED)
-       gtk_timeout_remove (dial->timer);
-      
-      if ((dial->policy != GTK_UPDATE_CONTINUOUS) &amp;&amp;
-         (dial->old_value != dial->adjustment->value))
-       gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
-    }
+<item> GTK_SELECTION_MULTIPLE -  The selection is NULL if no list
+                        items are selected or a GList pointer
+                        for the first selected item. That
+                        in turn points to a GList structure
+                        for the second selected item and so
+                        on.
 
-  return FALSE;
-}
+<item> GTK_SELECTION_EXTENDED - The selection is always NULL.
+</itemize>
 
-static gint
-gtk_dial_motion_notify (GtkWidget      *widget,
-                        GdkEventMotion *event)
-{
-  GtkDial *dial;
-  GdkModifierType mods;
-  gint x, y, mask;
+The default is GTK_SELECTION_MULTIPLE.
 
-  g_return_val_if_fail (widget != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (widget), FALSE);
-  g_return_val_if_fail (event != NULL, FALSE);
+<!-- ----------------------------------------------------------------- -->
+<sect1> Signals
+<p>
+<tscreen><verb>
+void selection_changed( GtkList *list );
+</verb></tscreen>
 
-  dial = GTK_DIAL (widget);
+This signal will be invoked whenever the selection field of a GtkList
+has changed. This happens when a child of the GtkList got selected or
+deselected.
 
-  if (dial->button != 0)
-    {
-      x = event->x;
-      y = event->y;
+<tscreen><verb>
+void select_child( GtkList   *list,
+                   GtkWidget *child);
+</verb></tscreen>
 
-      if (event->is_hint || (event->window != widget->window))
-       gdk_window_get_pointer (widget->window, &amp;x, &amp;y, &amp;mods);
+This signal is invoked when a child of the GtkList is about to get
+selected. This happens mainly on calls to gtk_list_select_item(),
+gtk_list_select_child(), button presses and sometimes indirectly
+triggered on some else occasions where children get added to or
+removed from the GtkList.
 
-      switch (dial->button)
-       {
-       case 1:
-         mask = GDK_BUTTON1_MASK;
-         break;
-       case 2:
-         mask = GDK_BUTTON2_MASK;
-         break;
-       case 3:
-         mask = GDK_BUTTON3_MASK;
-         break;
-       default:
-         mask = 0;
-         break;
-       }
+<tscreen><verb>
+void unselect_child( GtkList   *list,
+                     GtkWidget *child );
+</verb></tscreen>
 
-      if (mods &amp; mask)
-       gtk_dial_update_mouse (dial, x,y);
-    }
+This signal is invoked when a child of the GtkList is about to get
+deselected. This happens mainly on calls to gtk_list_unselect_item(),
+gtk_list_unselect_child(), button presses and sometimes indirectly
+triggered on some else occasions where children get added to or
+removed from the GtkList.
 
-  return FALSE;
-}
+<!-- ----------------------------------------------------------------- -->
+<sect1> Functions
+<p>
+<tscreen><verb>
+guint gtk_list_get_type( void );
+</verb></tscreen>
 
-static gint
-gtk_dial_timer (GtkDial *dial)
-{
-  g_return_val_if_fail (dial != NULL, FALSE);
-  g_return_val_if_fail (GTK_IS_DIAL (dial), FALSE);
+Returns the `GtkList' type identifier.
 
-  if (dial->policy == GTK_UPDATE_DELAYED)
-    gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
+<tscreen><verb>
+GtkWidget *gtk_list_new( void );
+</verb></tscreen>
 
-  return FALSE;
-}
+Create a new GtkList object. The new widget is returned as a pointer
+to a GtkWidget object. NULL is returned on failure.
 
-static void
-gtk_dial_update_mouse (GtkDial *dial, gint x, gint y)
-{
-  gint xc, yc;
-  gfloat old_value;
+<tscreen><verb>
+void gtk_list_insert_items( GtkList *list,
+                            GList   *items,
+                            gint     position );
+</verb></tscreen>
 
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+Insert list items into the list, starting at <tt/position/.
+<tt/items/ is a doubly linked list where each nodes data pointer is
+expected to point to a newly created GtkListItem.  The GList nodes of
+<tt/items/ are taken over by the list.
 
-  xc = GTK_WIDGET(dial)->allocation.width / 2;
-  yc = GTK_WIDGET(dial)->allocation.height / 2;
+<tscreen><verb>
+void gtk_list_append_items( GtkList *list,
+                            GList   *items);
+</verb></tscreen>
 
-  old_value = dial->adjustment->value;
-  dial->angle = atan2(yc-y, x-xc);
+Insert list items just like gtk_list_insert_items() at the end of the
+list. The GList nodes of <tt/items/ are taken over by the list.
 
-  if (dial->angle < -M_PI/2.)
-    dial->angle += 2*M_PI;
+<tscreen><verb>
+void gtk_list_prepend_items( GtkList *list,
+                             GList   *items);
+</verb></tscreen>
 
-  if (dial->angle < -M_PI/6)
-    dial->angle = -M_PI/6;
+Insert list items just like gtk_list_insert_items() at the very
+beginning of the list. The GList nodes of <tt/items/ are taken over by
+the list.
 
-  if (dial->angle > 7.*M_PI/6.)
-    dial->angle = 7.*M_PI/6.;
+<tscreen><verb>
+void gtk_list_remove_items( GtkList *list,
+                            GList   *items);
+</verb></tscreen>
 
-  dial->adjustment->value = dial->adjustment->lower + (7.*M_PI/6 - dial->angle) *
-    (dial->adjustment->upper - dial->adjustment->lower) / (4.*M_PI/3.);
+Remove list items from the list. <tt/items/ is a doubly linked list
+where each nodes data pointer is expected to point to a direct child
+of list. It is the callers responsibility to make a call to
+g_list_free(items) afterwards. Also the caller has to destroy the list
+items himself.
 
-  if (dial->adjustment->value != old_value)
-    {
-      if (dial->policy == GTK_UPDATE_CONTINUOUS)
-       {
-         gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
-       }
-      else
-       {
-         gtk_widget_draw (GTK_WIDGET(dial), NULL);
+<tscreen><verb>
+void gtk_list_clear_items( GtkList *list,
+                           gint start,
+                           gint end );
+</verb></tscreen>
 
-         if (dial->policy == GTK_UPDATE_DELAYED)
-           {
-             if (dial->timer)
-               gtk_timeout_remove (dial->timer);
+Remove and destroy list items from the list. A widget is affected if
+its current position within the list is in the range specified by
+<tt/start/ and <tt/end/.
 
-             dial->timer = gtk_timeout_add (SCROLL_DELAY_LENGTH,
-                                            (GtkFunction) gtk_dial_timer,
-                                            (gpointer) dial);
-           }
-       }
-    }
-}
+<tscreen><verb>
+void gtk_list_select_item( GtkList *list,
+                           gint     item );
+</verb></tscreen>
 
-static void
-gtk_dial_update (GtkDial *dial)
-{
-  gfloat new_value;
-  
-  g_return_if_fail (dial != NULL);
-  g_return_if_fail (GTK_IS_DIAL (dial));
+Invoke the select_child signal for a list item specified through its
+current position within the list.
 
-  new_value = dial->adjustment->value;
-  
-  if (new_value < dial->adjustment->lower)
-    new_value = dial->adjustment->lower;
+<tscreen><verb>
+void gtk_list_unselect_item( GtkList *list,
+                             gint     item);
+</verb></tscreen>
 
-  if (new_value > dial->adjustment->upper)
-    new_value = dial->adjustment->upper;
+Invoke the unselect_child signal for a list item specified through its
+current position within the list.
 
-  if (new_value != dial->adjustment->value)
-    {
-      dial->adjustment->value = new_value;
-      gtk_signal_emit_by_name (GTK_OBJECT (dial->adjustment), "value_changed");
-    }
+<tscreen><verb>
+void gtk_list_select_child( GtkList *list,
+                            GtkWidget *child);
+</verb></tscreen>
 
-  dial->angle = 7.*M_PI/6. - (new_value - dial->adjustment->lower) * 4.*M_PI/3. /
-    (dial->adjustment->upper - dial->adjustment->lower);
+Invoke the select_child signal for the specified child.
 
-  gtk_widget_draw (GTK_WIDGET(dial), NULL);
-}
+<tscreen><verb>
+void gtk_list_unselect_child( GtkList   *list,
+                              GtkWidget *child);
+</verb></tscreen>
 
-static void
-gtk_dial_adjustment_changed (GtkAdjustment *adjustment,
-                             gpointer       data)
-{
-  GtkDial *dial;
+Invoke the unselect_child signal for the specified child.
 
-  g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
+<tscreen><verb>
+gint gtk_list_child_position( GtkList *list,
+                              GtkWidget *child);
+</verb></tscreen>
 
-  dial = GTK_DIAL (data);
+Return the position of <tt/child/ within the list. "-1" is returned on
+failure.
 
-  if ((dial->old_value != adjustment->value) ||
-      (dial->old_lower != adjustment->lower) ||
-      (dial->old_upper != adjustment->upper))
-    {
-      gtk_dial_update (dial);
+<tscreen><verb>
+void gtk_list_set_selection_mode( GtkList         *list,
+                                  GtkSelectionMode mode );
+</verb></tscreen>
 
-      dial->old_value = adjustment->value;
-      dial->old_lower = adjustment->lower;
-      dial->old_upper = adjustment->upper;
-    }
-}
+Set the selection mode MODE which can be of GTK_SELECTION_SINGLE,
+GTK_SELECTION_BROWSE, GTK_SELECTION_MULTIPLE or
+GTK_SELECTION_EXTENDED.
 
-static void
-gtk_dial_adjustment_value_changed (GtkAdjustment *adjustment,
-                                   gpointer       data)
-{
-  GtkDial *dial;
+<tscreen><verb>
+GtkList *GTK_LIST( gpointer obj );
+</verb></tscreen>
 
-  g_return_if_fail (adjustment != NULL);
-  g_return_if_fail (data != NULL);
+Cast a generic pointer to `GtkList *'. *Note Standard Macros::, for
+more info.
 
-  dial = GTK_DIAL (data);
+<tscreen><verb>
+GtkListClass *GTK_LIST_CLASS( gpointer class);
+</verb></tscreen>
 
-  if (dial->old_value != adjustment->value)
-    {
-      gtk_dial_update (dial);
+Cast a generic pointer to `GtkListClass*'. *Note Standard Macros::,
+for more info.
 
-      dial->old_value = adjustment->value;
-    }
-}
-/* example-end */
+<tscreen><verb>
+gint GTK_IS_LIST( gpointer obj);
 </verb></tscreen>
 
+Determine if a generic pointer refers to a `GtkList' object. *Note
+Standard Macros::, for more info.
+
 <!-- ----------------------------------------------------------------- -->
-<sect1> Scribble
+<sect1> Example
 <p>
+Following is an example program that will print out the changes of the
+selection of a GtkList, and lets you "arrest" list items into a prison
+by selecting them with the rightmost mouse button.
+
 <tscreen><verb>
-/* example-start scribble-simple scribble-simple.c */
+/* example-start list list.c */
 
-/* GTK - The GIMP Toolkit
- * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+/* Include the gtk+ header files
+ * Include stdio.h, we need that for the printf() function
  */
+#include        <gtk/gtk.h>
+#include        <stdio.h>
 
-#include <gtk/gtk.h>
-
-/* Backing pixmap for drawing area */
-static GdkPixmap *pixmap = NULL;
+/* This is our data identification string to store
+ * data in list items
+ */
+const gchar *list_item_data_key="list_item_data";
 
-/* Create a new backing pixmap of the appropriate size */
-static gint
-configure_event (GtkWidget *widget, GdkEventConfigure *event)
-{
-  if (pixmap)
-    gdk_pixmap_unref(pixmap);
 
-  pixmap = gdk_pixmap_new(widget->window,
-                         widget->allocation.width,
-                         widget->allocation.height,
-                         -1);
-  gdk_draw_rectangle (pixmap,
-                     widget->style->white_gc,
-                     TRUE,
-                     0, 0,
-                     widget->allocation.width,
-                     widget->allocation.height);
+/* prototypes for signal handler that we are going to connect
+ * to the GtkList widget
+ */
+static void  sigh_print_selection( GtkWidget *gtklist,
+                                   gpointer   func_data);
 
-  return TRUE;
-}
+static void  sigh_button_event( GtkWidget      *gtklist,
+                                GdkEventButton *event,
+                                GtkWidget      *frame );
 
-/* Redraw the screen from the backing pixmap */
-static gint
-expose_event (GtkWidget *widget, GdkEventExpose *event)
-{
-  gdk_draw_pixmap(widget->window,
-                 widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
-                 pixmap,
-                 event->area.x, event->area.y,
-                 event->area.x, event->area.y,
-                 event->area.width, event->area.height);
 
-  return FALSE;
-}
+/* Main function to set up the user interface */
 
-/* Draw a rectangle on the screen */
-static void
-draw_brush (GtkWidget *widget, gdouble x, gdouble y)
-{
-  GdkRectangle update_rect;
+gint main (int    argc,
+           gchar *argv[])
+{                                  
+    GtkWidget *separator;
+    GtkWidget *window;
+    GtkWidget *vbox;
+    GtkWidget *scrolled_window;
+    GtkWidget *frame;
+    GtkWidget *gtklist;
+    GtkWidget *button;
+    GtkWidget *list_item;
+    GList *dlist;
+    guint i;
+    gchar buffer[64];
+    
+    
+    /* Initialize gtk+ (and subsequently gdk) */
 
-  update_rect.x = x - 5;
-  update_rect.y = y - 5;
-  update_rect.width = 10;
-  update_rect.height = 10;
-  gdk_draw_rectangle (pixmap,
-                     widget->style->black_gc,
-                     TRUE,
-                     update_rect.x, update_rect.y,
-                     update_rect.width, update_rect.height);
-  gtk_widget_draw (widget, &amp;update_rect);
+    gtk_init(&amp;argc, &amp;argv);
+    
+    
+    /* Create a window to put all the widgets in
+     * connect gtk_main_quit() to the "destroy" event of
+     * the window to handle window manager close-window-events
+     */
+    window=gtk_window_new(GTK_WINDOW_TOPLEVEL);
+    gtk_window_set_title(GTK_WINDOW(window), "GtkList Example");
+    gtk_signal_connect(GTK_OBJECT(window),
+                      "destroy",
+                      GTK_SIGNAL_FUNC(gtk_main_quit),
+                      NULL);
+    
+    
+    /* Inside the window we need a box to arrange the widgets
+     * vertically */
+    vbox=gtk_vbox_new(FALSE, 5);
+    gtk_container_set_border_width(GTK_CONTAINER(vbox), 5);
+    gtk_container_add(GTK_CONTAINER(window), vbox);
+    gtk_widget_show(vbox);
+    
+    /* This is the scrolled window to put the GtkList widget inside */
+    scrolled_window=gtk_scrolled_window_new(NULL, NULL);
+    gtk_widget_set_usize(scrolled_window, 250, 150);
+    gtk_container_add(GTK_CONTAINER(vbox), scrolled_window);
+    gtk_widget_show(scrolled_window);
+    
+    /* Create the GtkList widget.
+     * Connect the sigh_print_selection() signal handler
+     * function to the "selection_changed" signal of the GtkList
+     * to print out the selected items each time the selection
+     * has changed */
+    gtklist=gtk_list_new();
+    gtk_scrolled_window_add_with_viewport( GTK_SCROLLED_WINDOW(scrolled_window),
+                                           gtklist);
+    gtk_widget_show(gtklist);
+    gtk_signal_connect(GTK_OBJECT(gtklist),
+                      "selection_changed",
+                      GTK_SIGNAL_FUNC(sigh_print_selection),
+                      NULL);
+    
+    /* We create a "Prison" to put a list item in ;) */
+    frame=gtk_frame_new("Prison");
+    gtk_widget_set_usize(frame, 200, 50);
+    gtk_container_set_border_width(GTK_CONTAINER(frame), 5);
+    gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_OUT);
+    gtk_container_add(GTK_CONTAINER(vbox), frame);
+    gtk_widget_show(frame);
+    
+    /* Connect the sigh_button_event() signal handler to the GtkList
+     * which will handle the "arresting" of list items
+     */
+    gtk_signal_connect(GTK_OBJECT(gtklist),
+                      "button_release_event",
+                      GTK_SIGNAL_FUNC(sigh_button_event),
+                      frame);
+    
+    /* Create a separator */
+    separator=gtk_hseparator_new();
+    gtk_container_add(GTK_CONTAINER(vbox), separator);
+    gtk_widget_show(separator);
+    
+    /* Finally create a button and connect it's "clicked" signal
+     * to the destruction of the window */
+    button=gtk_button_new_with_label("Close");
+    gtk_container_add(GTK_CONTAINER(vbox), button);
+    gtk_widget_show(button);
+    gtk_signal_connect_object(GTK_OBJECT(button),
+                             "clicked",
+                             GTK_SIGNAL_FUNC(gtk_widget_destroy),
+                             GTK_OBJECT(window));
+    
+    
+    /* Now we create 5 list items, each having it's own
+     * label and add them to the GtkList using gtk_container_add()
+     * Also we query the text string from the label and
+     * associate it with the list_item_data_key for each list item
+     */
+    for (i=0; i<5; i++) {
+       GtkWidget       *label;
+       gchar           *string;
+       
+       sprintf(buffer, "ListItemContainer with Label #%d", i);
+       label=gtk_label_new(buffer);
+       list_item=gtk_list_item_new();
+       gtk_container_add(GTK_CONTAINER(list_item), label);
+       gtk_widget_show(label);
+       gtk_container_add(GTK_CONTAINER(gtklist), list_item);
+       gtk_widget_show(list_item);
+       gtk_label_get(GTK_LABEL(label), &amp;string);
+       gtk_object_set_data(GTK_OBJECT(list_item),
+                           list_item_data_key,
+                           string);
+    }
+    /* Here, we are creating another 5 labels, this time
+     * we use gtk_list_item_new_with_label() for the creation
+     * we can't query the text string from the label because
+     * we don't have the labels pointer and therefore
+     * we just associate the list_item_data_key of each
+     * list item with the same text string.
+     * For adding of the list items we put them all into a doubly
+     * linked list (GList), and then add them by a single call to
+     * gtk_list_append_items().
+     * Because we use g_list_prepend() to put the items into the
+     * doubly linked list, their order will be descending (instead
+     * of ascending when using g_list_append())
+     */
+    dlist=NULL;
+    for (; i<10; i++) {
+       sprintf(buffer, "List Item with Label %d", i);
+       list_item=gtk_list_item_new_with_label(buffer);
+       dlist=g_list_prepend(dlist, list_item);
+       gtk_widget_show(list_item);
+       gtk_object_set_data(GTK_OBJECT(list_item),
+                           list_item_data_key,
+                           "ListItem with integrated Label");
+    }
+    gtk_list_append_items(GTK_LIST(gtklist), dlist);
+    
+    /* Finally we want to see the window, don't we? ;) */
+    gtk_widget_show(window);
+    
+    /* Fire up the main event loop of gtk */
+    gtk_main();
+    
+    /* We get here after gtk_main_quit() has been called which
+     * happens if the main window gets destroyed
+     */
+    return(0);
 }
 
-static gint
-button_press_event (GtkWidget *widget, GdkEventButton *event)
+/* This is the signal handler that got connected to button
+ * press/release events of the GtkList
+ */
+void sigh_button_event( GtkWidget      *gtklist,
+                        GdkEventButton *event,
+                        GtkWidget      *frame )
 {
-  if (event->button == 1 &amp;&amp; pixmap != NULL)
-    draw_brush (widget, event->x, event->y);
-
-  return TRUE;
+    /* We only do something if the third (rightmost mouse button
+     * was released
+     */
+    if (event->type==GDK_BUTTON_RELEASE &amp;&amp;
+       event->button==3) {
+       GList           *dlist, *free_list;
+       GtkWidget       *new_prisoner;
+       
+       /* Fetch the currently selected list item which
+        * will be our next prisoner ;)
+        */
+       dlist=GTK_LIST(gtklist)->selection;
+       if (dlist)
+               new_prisoner=GTK_WIDGET(dlist->data);
+       else
+               new_prisoner=NULL;
+       
+       /* Look for already imprisoned list items, we
+        * will put them back into the list.
+        * Remember to free the doubly linked list that
+        * gtk_container_children() returns
+        */
+       dlist=gtk_container_children(GTK_CONTAINER(frame));
+       free_list=dlist;
+       while (dlist) {
+           GtkWidget       *list_item;
+           
+           list_item=dlist->data;
+           
+           gtk_widget_reparent(list_item, gtklist);
+           
+           dlist=dlist->next;
+       }
+       g_list_free(free_list);
+       
+       /* If we have a new prisoner, remove him from the
+        * GtkList and put him into the frame "Prison".
+        * We need to unselect the item first.
+        */
+       if (new_prisoner) {
+           GList   static_dlist;
+           
+           static_dlist.data=new_prisoner;
+           static_dlist.next=NULL;
+           static_dlist.prev=NULL;
+           
+           gtk_list_unselect_child(GTK_LIST(gtklist),
+                                   new_prisoner);
+           gtk_widget_reparent(new_prisoner, frame);
+       }
+    }
 }
 
-static gint
-motion_notify_event (GtkWidget *widget, GdkEventMotion *event)
+/* This is the signal handler that gets called if GtkList
+ * emits the "selection_changed" signal
+ */
+void sigh_print_selection( GtkWidget *gtklist,
+                           gpointer   func_data)
 {
-  int x, y;
-  GdkModifierType state;
-
-  if (event->is_hint)
-    gdk_window_get_pointer (event->window, &amp;x, &amp;y, &amp;state);
-  else
-    {
-      x = event->x;
-      y = event->y;
-      state = event->state;
+    GList   *dlist;
+    
+    /* Fetch the doubly linked list of selected items
+     * of the GtkList, remember to treat this as read-only!
+     */
+    dlist=GTK_LIST(gtklist)->selection;
+    
+    /* If there are no selected items there is nothing more
+     * to do than just telling the user so
+     */
+    if (!dlist) {
+       g_print("Selection cleared\n");
+       return;
     }
+    /* Ok, we got a selection and so we print it
+     */
+    g_print("The selection is a ");
     
-  if (state &amp; GDK_BUTTON1_MASK &amp;&amp; pixmap != NULL)
-    draw_brush (widget, x, y);
-  
-  return TRUE;
+    /* Get the list item from the doubly linked list
+     * and then query the data associated with list_item_data_key.
+     * We then just print it */
+    while (dlist) {
+       GtkObject       *list_item;
+       gchar           *item_data_string;
+       
+       list_item=GTK_OBJECT(dlist->data);
+       item_data_string=gtk_object_get_data(list_item,
+                                            list_item_data_key);
+       g_print("%s ", item_data_string);
+       
+       dlist=dlist->next;
+    }
+    g_print("\n");
 }
+/* example-end */
+</verb></tscreen>
 
-void
-quit ()
-{
-  gtk_exit (0);
-}
+<!-- ----------------------------------------------------------------- -->
+<sect1> List Item Widget
+<p>
+The GtkListItem widget is designed to act as a container holding up to
+one child, providing functions for selection/deselection just like the
+GtkList widget requires them for its children.
 
-int
-main (int argc, char *argv[])
-{
-  GtkWidget *window;
-  GtkWidget *drawing_area;
-  GtkWidget *vbox;
+A GtkListItem has its own window to receive events and has its own
+background color which is usually white.
 
-  GtkWidget *button;
+As it is directly derived from a GtkItem it can be treated as such by
+using the GTK_ITEM(ListItem) macro, see the GtkItem widget for more on
+this. Usually a GtkListItem just holds a label to identify e.g. a
+filename within a GtkList -- therefore the convenience function
+gtk_list_item_new_with_label() is provided. The same effect can be
+achieved by creating a GtkLabel on its own, setting its alignment to
+xalign=0 and yalign=0.5 with a subsequent container addition to the
+GtkListItem.
 
-  gtk_init (&amp;argc, &amp;argv);
+As one is not forced to add a GtkLabel to a GtkListItem, you could
+also add a GtkVBox or a GtkArrow etc. to the GtkListItem.
 
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_widget_set_name (window, "Test Input");
+<!-- ----------------------------------------------------------------- -->
+<sect1> Signals
+<p>
+A GtkListItem does not create new signals on its own, but inherits
+the signals of a GtkItem. *Note GtkItem::, for more info.
 
-  vbox = gtk_vbox_new (FALSE, 0);
-  gtk_container_add (GTK_CONTAINER (window), vbox);
-  gtk_widget_show (vbox);
+<!-- ----------------------------------------------------------------- -->
+<sect1> Functions
+<p>
+<tscreen><verb>
+guint gtk_list_item_get_type( void );
+</verb></tscreen>
 
-  gtk_signal_connect (GTK_OBJECT (window), "destroy",
-                     GTK_SIGNAL_FUNC (quit), NULL);
+Returns the `GtkListItem' type identifier.
 
-  /* Create the drawing area */
+<tscreen><verb>
+GtkWidget *gtk_list_item_new( void );
+</verb></tscreen>
 
-  drawing_area = gtk_drawing_area_new ();
-  gtk_drawing_area_size (GTK_DRAWING_AREA (drawing_area), 200, 200);
-  gtk_box_pack_start (GTK_BOX (vbox), drawing_area, TRUE, TRUE, 0);
+Create a new GtkListItem object. The new widget is returned as a
+pointer to a GtkWidget object. NULL is returned on failure.
 
-  gtk_widget_show (drawing_area);
+<tscreen><verb>
+GtkWidget *gtk_list_item_new_with_label( gchar *label );
+</verb></tscreen>
 
-  /* Signals used to handle backing pixmap */
+Create a new GtkListItem object, having a single GtkLabel as the sole
+child. The new widget is returned as a pointer to a GtkWidget
+object. NULL is returned on failure.
 
-  gtk_signal_connect (GTK_OBJECT (drawing_area), "expose_event",
-                     (GtkSignalFunc) expose_event, NULL);
-  gtk_signal_connect (GTK_OBJECT(drawing_area),"configure_event",
-                     (GtkSignalFunc) configure_event, NULL);
+<tscreen><verb>
+void gtk_list_item_select( GtkListItem *list_item );
+</verb></tscreen>
 
-  /* Event signals */
+This function is basically a wrapper around a call to gtk_item_select
+(GTK_ITEM (list_item)) which will emit the select signal.  *Note
+GtkItem::, for more info.
 
-  gtk_signal_connect (GTK_OBJECT (drawing_area), "motion_notify_event",
-                     (GtkSignalFunc) motion_notify_event, NULL);
-  gtk_signal_connect (GTK_OBJECT (drawing_area), "button_press_event",
-                     (GtkSignalFunc) button_press_event, NULL);
+<tscreen><verb>
+void gtk_list_item_deselect( GtkListItem *list_item );
+</verb></tscreen>
 
-  gtk_widget_set_events (drawing_area, GDK_EXPOSURE_MASK
-                        | GDK_LEAVE_NOTIFY_MASK
-                        | GDK_BUTTON_PRESS_MASK
-                        | GDK_POINTER_MOTION_MASK
-                        | GDK_POINTER_MOTION_HINT_MASK);
+This function is basically a wrapper around a call to
+gtk_item_deselect (GTK_ITEM (list_item)) which will emit the deselect
+signal.  *Note GtkItem::, for more info.
 
-  /* .. And a quit button */
-  button = gtk_button_new_with_label ("Quit");
-  gtk_box_pack_start (GTK_BOX (vbox), button, FALSE, FALSE, 0);
+<tscreen><verb>
+GtkListItem *GTK_LIST_ITEM( gpointer obj );
+</verb></tscreen>
 
-  gtk_signal_connect_object (GTK_OBJECT (button), "clicked",
-                            GTK_SIGNAL_FUNC (gtk_widget_destroy),
-                            GTK_OBJECT (window));
-  gtk_widget_show (button);
+Cast a generic pointer to `GtkListItem*'. *Note Standard Macros::, for
+more info.
 
-  gtk_widget_show (window);
+<tscreen><verb>
+GtkListItemClass *GTK_LIST_ITEM_CLASS( gpointer class );
+</verb></tscreen>
 
-  gtk_main ();
+Cast a generic pointer to GtkListItemClass*. *Note Standard Macros::,
+for more info.
 
-  return 0;
-}
-/* example-end */
+<tscreen><verb>
+gint GTK_IS_LIST_ITEM( gpointer obj );
 </verb></tscreen>
 
+Determine if a generic pointer refers to a `GtkListItem' object.
+*Note Standard Macros::, for more info.
+<!-- ----------------------------------------------------------------- -->
+<sect1> Example
+<p>
+Please see the GtkList example on this, which covers the usage of a
+GtkListItem as well.
+
+
 </article>